bzoj 3894: 文理分科

Description

文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠

结过)

小P所在的班级要进行文理分科。他的班级可以用一个n*m的矩阵进行

描述,每个格子代表一个同学的座位。每位同学必须从文科和理科中选择

一科。同学们在选择科目的时候会获得一个满意值。满意值按如下的方式

得到:

1.如果第i行第秒J的同学选择了文科,则他将获得art[i][j]的满意值,如

果选择理科,将得到science[i][j]的满意值。

2.如果第i行第J列的同学选择了文科,并且他相邻(两个格子相邻当且

仅当它们拥有一条相同的边)的同学全部选择了文科,则他会更开

心,所以会增加same_art[i][j]的满意值。

3.如果第i行第j列的同学选择了理科,并且他相邻的同学全部选择了理

科,则增加same_science[i]j[]的满意值。

小P想知道,大家应该如何选择,才能使所有人的满意值之和最大。请

告诉他这个最大值。

Input

第一行为两个正整数:n,m

接下来n术m个整数,表示art[i][j];

接下来n术m个整数.表示science[i][j];

接下来n术m个整数,表示same_art[i][j];

Output

输出为一个整数,表示最大的满意值之和

Sample Input

3 4

13 2 4 13

7 13 8 12

18 17 0 5

8 13 15 4

11 3 8 11

11 18 6 5

1 2 3 4

4 2 3 2

3 1 0 4

3 2 3 2

0 2 2 1

0 2 4 4

Sample Output

152

HINT

样例说明

1表示选择文科,0表示选择理科,方案如下:

1  0  0  1

0  1  0  0

1  0  0  0

N,M<=100,读入数据均<=500

Source

一道很不错的最小割模型混杂题,画了好久才跑对QAQ...

// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#define RG register
using namespace std;
typedef long long ll;
const int N=1000050;
const int Inf=19260817;
int gi(){
  int x=0,flag=1;
  char ch=getchar();
  while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) flag=-1;ch=getchar();}
  while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
  return x*flag;
}
int head[N],nxt[N],to[N],s[N],cnt=1,n,m;
int a[550][550],b[550][550],c[550][550],d[550][550];
int id[550][550][3],tt,S,T,level[N],q[N*5],F,tot;
int mx[5]={1,-1,0,0},my[5]={0,0,1,-1};
inline void Addedge(RG int x,RG int y,RG int z) {
  to[++cnt]=y,s[cnt]=z,nxt[cnt]=head[x],head[x]=cnt;
}
inline void lnk(RG int x,RG int y,RG int z){
  Addedge(x,y,z),Addedge(y,x,0);
}
inline bool bfs(){
  for(RG int i=S;i<=T;i++) level[i]=0;
  q[0]=S,level[S]=1;int t=0,sum=1;
  while(t<sum){
    int x=q[t++];
    if(x==T) return 1;
    for(RG int i=head[x];i;i=nxt[i]){
      int y=to[i];
      if(s[i]&&level[y]==0){
	level[y]=level[x]+1;
	q[sum++]=y;
      }
    }
  }
  return 0;
}
inline int dfs(RG int x,int maxf){
  if(x==T) return maxf;
  int ret=0;
  for(RG int i=head[x];i;i=nxt[i]){
    int y=to[i],f=s[i];
    if(level[y]==level[x]+1&&f){
      int minn=min(f,maxf-ret);
      f=dfs(y,minn);
      s[i]-=f,s[i^1]+=f,ret+=f;
      if(ret==maxf) break;
    }
  }
  if(!ret) level[x]=0;
  return ret;
}
inline void Dinic(){
  while(bfs()) F+=dfs(S,Inf);
}
int main(){
  n=gi(),m=gi();
  for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++){
      a[i][j]=gi(),tot+=a[i][j];
    }
  for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++){
      b[i][j]=gi();tot+=b[i][j];
    }
  for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++){
      c[i][j]=gi();tot+=c[i][j];
    }
  for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++){
      d[i][j]=gi();tot+=d[i][j];
    }
  for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
      for(int k=0;k<3;k++){
	id[i][j][k]=++tt;
      }
  S=0,T=tt+1;
  for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++){
      lnk(S,id[i][j][0],a[i][j]);
      lnk(id[i][j][0],T,b[i][j]);
      lnk(id[i][j][0],id[i][j][1],Inf);
      lnk(id[i][j][2],id[i][j][0],Inf);
      lnk(id[i][j][1],T,d[i][j]);
      lnk(S,id[i][j][2],c[i][j]);
      for(int k=0;k<4;k++){
	int x=i+mx[k],y=j+my[k];
	if(1<=x&&x<=n&&1<=y&&y<=m){
	  lnk(id[x][y][0],id[i][j][1],Inf);
	  lnk(id[i][j][2],id[x][y][0],Inf);
	}
      }
    }
  Dinic();printf("%d\n",tot-F);
  return 0;
}
时间: 2024-10-18 03:12:50

bzoj 3894: 文理分科的相关文章

BZOJ 3894: 文理分科 [最小割]

3894: 文理分科 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 674  Solved: 392[Submit][Status][Discuss] Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位同学必须从文科和理科中选择 一科.同学们在选择科目的时候会获得一个满意值.满意值按如下的方式 得到

[BZOJ 3894] 文理分科 【最小割】

题目链接:BZOJ - 3894 题目分析 最小割模型,设定一个点与 S 相连表示选文,与 T 相连表示选理. 那么首先要加上所有可能获得的权值,然后减去最小割,即不能获得的权值. 那么对于每个点,从 S 向它连权值为它选文的价值的边,从它向 T 连权值为它选理的价值的边. 对于一个点,它和与它相邻的点构成了一个集合,这个集合如果都选文,可以获得一个价值v1,如果都选理,可以获得一个价值 v2. 只要这个集合中有一个点选文,就无法获得 v2,只要有一个点选理,就无法获得 v1. 那么处理方式就是

【BZOJ 3894】 文理分科

3894: 文理分科 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 194 Solved: 122 [Submit][Status][Discuss] Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位同学必须从文科和理科中选择 一科.同学们在选择科目的时候会获得一个满意值.满意值按如下的方式 得到

【BZOJ3894】文理分科(最小割)

[BZOJ3894]文理分科(最小割) 题面 BZOJ Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位同学必须从文科和理科中选择 一科.同学们在选择科目的时候会获得一个满意值.满意值按如下的方式 得到: 1.如果第i行第秒J的同学选择了文科,则他将获得art[i][j]的满意值,如 果选择理科,将得到science[i][j]的满意值. 2.如

【BZOJ】【3894】文理分科

网络流/最小割 rausen大爷太神辣-作为一个蒟蒻还是搬运题解吧…… 很明显的一道网络流题.. 首先把所有值的加起来,再减掉网络流最小割值就好了,问题就是如何建图.这貌似也是考了好多次了的... 把每个人抽象成一个点p,则 先是S向p连边,流量为选文科的高兴值,p向T连边,流量为选理科的高兴值. 然后是same的条件,对每个人新建两个点p1, p2 S向p1连边,流量为文科same的高兴值,p1向相邻点和自己的p连边,流量为inf p2相T连边,流量为理科same的高兴值,相邻点和自己的p向p

BZOJ3894: 文理分科

Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位同学必须从文科和理科中选择 一科.同学们在选择科目的时候会获得一个满意值.满意值按如下的方式 得到: 1.如果第i行第秒J的同学选择了文科,则他将获得art[i][j]的满意值,如 果选择理科,将得到science[i][j]的满意值. 2.如果第i行第J列的同学选择了文科,并且他相邻(两个格子相邻

第八回(二)新年晚会艺压群芳 文理分科三人聚首

(二) 第八回 新年晚会艺压群芳 文理分科三人聚首 林二忆起数月前旧事,不禁自己笑了起来.期间小谢数次搭桥牵线,林二虽未言谢,自是感激.以至此后多大的事,皆可担待,不过这也是后话.却说光阴飞逝,不觉林二入学已近一载.书院也例行分科文理,林二,阿四一干人等,均素来喜吟古人诗句,势必凑那文科数.小谢心宽体胖,倒不十分热心这事,文科报名时,林二便也将他名字钩上. 谁知当日暑期补习,这三人便同处一班,阿四不禁感慨道:“莫非古人云,风云际会,机缘巧合,真有这事.”说毕三人便哈哈大笑,往阿清店喝可乐去,是时

第八回 新年晚会艺压群芳 文理分科三人聚首[林大帅作品选]

(一)第八回 新年晚会艺压群芳 文理分科三人聚首 诗曰: 舞袖从容歌不尽 ,顿织梦幻望夕阴, 红粉皆寂何处寻 ,阅尽芳菲更伤心. 话说林二于教室前,与那小谢堂妹相识,谁料那姑娘望了林二一眼,竟莫名一溜烟跑了.小谢叫喊不及,只得双手一拍,一脸不解.忙向林二解释道,“我这阿妹平日里落落大方,今儿着实奇怪.”林二方才和她对眼,魂儿又被勾走了,只是望着莉莉二人拐进初院,不作理会.唯那留声机中,梅姐歌声不绝:“一天想,想到过去但已晚...”日后有好事者,为记这二人相遇,乱掐七律一首.说书人也花好大功夫,在

BZOJ_3894_文理分科&amp;&amp;BZOJ_2127_happiness_最小割

BZOJ_3894_文理分科_最小割 Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位同学必须从文科和理科中选择 一科.同学们在选择科目的时候会获得一个满意值.满意值按如下的方式 得到: 1.如果第i行第秒J的同学选择了文科,则他将获得art[i][j]的满意值,如 果选择理科,将得到science[i][j]的满意值. 2.如果第i行第J列的同