首页 > 代码库 > BZOJ 3894 文理分科
BZOJ 3894 文理分科
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
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
DINIC模板题。很经典。又死在点、边数上,这个确实需要好好算一算。还有,if的判断……(本人是智障)
1 /************************************************************** 2 Problem: 3894 3 User: Doggu 4 Language: C++ 5 Result: Accepted 6 Time:2380 ms 7 Memory:19036 kb 8 ****************************************************************/ 9 10 #include <cstdio>11 #include <algorithm>12 #include <cstring>13 #include <queue>14 #define pos(x,y) ((x-1)*m+y)15 const int N = 200200;16 const int M = 1001001;17 const int dx[] = {0,1,-1,0,0};18 const int dy[] = {0,0,0,1,-1};19 struct Edge {int v,upre,cap,flow;}g[M];20 int head[N], ne = 0;21 inline void adde(int u,int v,int cap) {22 g[ne]=(Edge){v,head[u],cap,0};head[u]=ne++;23 g[ne]=(Edge){u,head[v],0,0};head[v]=ne++;24 }25 int n, m, s, t, x, sum, INF=0x3f3f3f3f;26 int d[N];27 bool vis[N];28 std::queue<int> q;29 bool BFS() {30 memset(vis, 0, sizeof(vis));31 while(!q.empty()) q.pop();32 d[s]=0;vis[s]=1;q.push(s);33 while(!q.empty()) {34 int u=q.front();q.pop();35 for( int i = head[u]; i != -1; i = g[i].upre ) {36 int v=g[i].v;37 if(!vis[v] && g[i].cap>g[i].flow) d[v]=d[u]+1,vis[v]=1,q.push(v);38 }39 }40 return vis[t];41 }42 int cur[N];43 int DFS(int u,int a) {44 if(u == t||a == 0) return a;45 int f, flow = 0;46 for( int& i = cur[u]; i != -1; i = g[i].upre ) {47 int v=g[i].v;48 if(d[v]==d[u]+1&&(f=DFS(v,std::min(a,g[i].cap-g[i].flow)))>0) {49 g[i].flow+=f;g[i^1].flow-=f;a-=f;flow+=f;50 if(a==0) break;51 }52 }53 return flow;54 }55 void maxflow() {56 int flow = 0;57 while(BFS()) {58 memcpy(cur,head,sizeof(head));59 flow+=DFS(s,INF);60 }61 printf("%d\n",sum-flow);62 }63 int main() {64 memset(head,-1,sizeof(head));65 scanf("%d%d",&n,&m);66 s=0;t=32999;67 for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) {68 scanf("%d",&x);sum+=x;adde(s,pos(i,j),x);69 }70 for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) {71 scanf("%d",&x);sum+=x;adde(pos(i,j),t,x);72 }73 for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) {74 scanf("%d",&x);sum+=x;adde(s,pos(n,m)+pos(i,j),x);75 for( int d = 0; d <= 4; d++ ) if(1<=i+dx[d]&&i+dx[d]<=n&&1<=j+dy[d]&&j+dy[d]<=m) adde(pos(n,m)+pos(i,j),pos(i+dx[d],j+dy[d]),INF);76 }77 for( int i = 1; i <= n; i++ ) for( int j = 1; j <= m; j++ ) {78 scanf("%d",&x);sum+=x;adde(2*pos(n,m)+pos(i,j),t,x);79 for( int d = 0; d <= 4; d++ ) if(1<=i+dx[d]&&i+dx[d]<=n&&1<=j+dy[d]&&j+dy[d]<=m) adde(pos(i+dx[d],j+dy[d]),2*pos(n,m)+pos(i,j),INF);80 }81 maxflow();82 return 0;83 }84
BZOJ 3894 文理分科
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。