bzoj2127&bzoj2132

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2127

http://www.lydsy.com/JudgeOnline/problem.php?id=2132

20160327

程序:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define visit(i,j) for(int i=g[j];i!=-1;i=es[i].n)
 7 #define INF 0x3fffffff
 8 using namespace std;
 9
10 struct e{int t,c,n;}; e es[500000]; int ess,g[20000];
11 inline void pe(int f,int t,int c){es[++ess]=(e){t,c,g[f]}; g[f]=ess; es[++ess]=(e){f,0,g[t]}; g[t]=ess;}
12 inline void pe2(int f,int t,int c){es[++ess]=(e){t,c,g[f]}; g[f]=ess; es[++ess]=(e){f,c,g[t]}; g[t]=ess;}
13 inline void init(){ess=-1; memset(g,-1,sizeof(g));}
14 queue <int> q; int h[20000];
15 bool bfs(int s,int t){
16     while(! q.empty())q.pop(); memset(h,-1,sizeof(h)); q.push(s); h[s]=0;
17     while(! q.empty()){
18         int x=q.front(); q.pop();
19         visit(i,x)if(es[i].c&&h[es[i].t]==-1){h[es[i].t]=h[x]+1; q.push(es[i].t);}
20     }
21     if(h[t]==-1)return 0;else return 1;
22 }
23 int dfs(int x,int t,int f){
24     if(x==t)return f; int u=0;
25     visit(i,x)if(es[i].c&&h[es[i].t]==h[x]+1){
26         int w=dfs(es[i].t,t,min(f,es[i].c));
27         f-=w; u+=w; es[i].c-=w; es[i^1].c+=w; if(f==0)return u;
28     }
29     if(!u)h[x]=-1; return u;
30 }
31 int dinic(int s,int t){int f=0; while(bfs(s,t))f+=dfs(s,t,INF); return f;}
32 int a1[200][200],a2[200][200],tot,n,m,s,t;
33 inline int cg(int x,int y){return (x-1)*m+y;}
34 int main(){
35     scanf("%d%d",&n,&m); tot=0;
36     inc(i,1,n)inc(j,1,m)scanf("%d",&a1[i][j]),tot+=a1[i][j],a1[i][j]<<=1;
37     inc(i,1,n)inc(j,1,m)scanf("%d",&a2[i][j]),tot+=a2[i][j],a2[i][j]<<=1;
38     s=0; t=n*m+1; init();
39     inc(i,1,n-1)inc(j,1,m){
40         int x; scanf("%d",&x); a1[i][j]+=x; a1[i+1][j]+=x; tot+=x; pe2(cg(i,j),cg(i+1,j),x);
41     }
42     inc(i,1,n-1)inc(j,1,m){
43         int x; scanf("%d",&x); a2[i][j]+=x; a2[i+1][j]+=x; tot+=x; pe2(cg(i,j),cg(i+1,j),x);
44     }
45     inc(i,1,n)inc(j,1,m-1){
46         int x; scanf("%d",&x); a1[i][j]+=x; a1[i][j+1]+=x; tot+=x; pe2(cg(i,j),cg(i,j+1),x);
47     }
48     inc(i,1,n)inc(j,1,m-1){
49         int x; scanf("%d",&x); a2[i][j]+=x; a2[i][j+1]+=x; tot+=x; pe2(cg(i,j),cg(i,j+1),x);
50     }
51     inc(i,1,n)inc(j,1,m){pe(s,cg(i,j),a1[i][j]); pe(cg(i,j),t,a2[i][j]);}
52     printf("%d",tot-(dinic(s,t)>>1));
53     return 0;
54 }

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define visit(i,j) for(int i=g[j];i!=-1;i=es[i].n)
 7 #define INF 0x3fffffff
 8 using namespace std;
 9
10 struct e{int t,c,n;}; e es[500000]; int ess,g[20000];
11 inline void pe(int f,int t,int c){es[++ess]=(e){t,c,g[f]}; g[f]=ess; es[++ess]=(e){f,0,g[t]}; g[t]=ess;}
12 inline void pe2(int f,int t,int c){es[++ess]=(e){t,c,g[f]}; g[f]=ess; es[++ess]=(e){f,c,g[t]}; g[t]=ess;}
13 inline void init(){ess=-1; memset(g,-1,sizeof(g));}
14 queue <int> q; int h[20000];
15 bool bfs(int s,int t){
16     while(! q.empty())q.pop(); memset(h,-1,sizeof(h)); q.push(s); h[s]=0;
17     while(! q.empty()){
18         int x=q.front(); q.pop();
19         visit(i,x)if(es[i].c&&h[es[i].t]==-1){h[es[i].t]=h[x]+1; q.push(es[i].t);}
20     }
21     if(h[t]==-1)return 0;else return 1;
22 }
23 int dfs(int x,int t,int f){
24     if(x==t)return f; int u=0;
25     visit(i,x)if(es[i].c&&h[es[i].t]==h[x]+1){
26         int w=dfs(es[i].t,t,min(f,es[i].c));
27         f-=w; u+=w; es[i].c-=w; es[i^1].c+=w; if(f==0)return u;
28     }
29     if(!u)h[x]=-1; return u;
30 }
31 int dinic(int s,int t){int f=0; while(bfs(s,t))f+=dfs(s,t,INF); return f;}
32 int a1[200][200],a2[200][200],a3[200][200],tot,n,m,s,t; bool col[200][200];
33 inline int cg(int x,int y){return (x-1)*m+y;}
34 int main(){
35     scanf("%d%d",&n,&m); tot=0;
36     inc(i,1,n)inc(j,1,m)scanf("%d",&a1[i][j]),tot+=a1[i][j];
37     inc(i,1,n)inc(j,1,m)scanf("%d",&a2[i][j]),tot+=a2[i][j];
38     inc(i,1,n)inc(j,1,m)scanf("%d",&a3[i][j]);
39     s=0; t=n*m+1; init();inc(i,1,n)inc(j,1,m){col[i][j]=(i+j)&1;}
40     inc(i,1,n)inc(j,1,m){
41         if(col[i][j])pe(s,cg(i,j),a1[i][j]),pe(cg(i,j),t,a2[i][j]);else pe(s,cg(i,j),a2[i][j]),pe(cg(i,j),t,a1[i][j]);
42         if(i!=n)pe2(cg(i,j),cg(i+1,j),a3[i][j]+a3[i+1][j]),tot+=(a3[i][j]+a3[i+1][j]);
43         if(j!=m)pe2(cg(i,j),cg(i,j+1),a3[i][j]+a3[i][j+1]),tot+=(a3[i][j]+a3[i][j+1]);
44     }
45     printf("%d",tot-dinic(s,t));
46     return 0;
47 }

题解:两道都是最小割问题。

第一题题解太难写,转黄学长的吧

利用最小割考虑。

对于原图中所有相邻的两个人A,B,我们建边:

s->A:cost[A文]+c[文][A][B]/2,s->B:cost[B文]+c[文][A][B]/2;

A->t:cost[A理]+c[理][A][B]/2,B->t:costB[理]+c[理][A][B]/2;

A<–>B:c[文][A][B]/2+c[理][A][B]/2

注意里面的AB之间的无向边是一门玄学,当它满载时表示AB分属不同集合,而且无向边不需要反向边,用的是普通图的插边方式。

还有那些除以2只要将cost*2,然后最后求出来的最小割除以2就行。

时间: 2024-10-06 00:42:54

bzoj2127&bzoj2132的相关文章

[转载]hzwer的bzoj题单

counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ1202 BZOJ1051 BZOJ1001 BZOJ1588 BZOJ1208 BZOJ1491 BZOJ1084 BZOJ1295 BZOJ3109 BZOJ1085 BZOJ1041 BZOJ1087 BZOJ3038 BZOJ1821 BZOJ1076 BZOJ2321 BZOJ1934 BZOJ

bzoj2132圈地计划

bzoj2132圈地计划 题意: 一块土地可以纵横划分为N×M块小区域.于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益.而如果区域(i,j)相邻(相邻是指两个格子有公共边)有K块(显然K不超过4)类型不同于(i,j)的区域,则这块区域能增加k×Cij收益.已知收益矩阵A,B,C,求收益最大值. 题解: 因为附加收益不是两两之间的,所以不用考虑除以2的问题.由于需要两块土地属性不同,所以对整个棋盘进行黑白染色.如果一块土地A为黑色,则s->A :c[A商] A->T

【BZOJ2132】圈地计划 最小割

[BZOJ2132]圈地计划 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域.GDOI要求将这些区域分为商业区和工业区来开发.根据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值.更具体点,对于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益.另外不同的区域连在一起可以得

[BZOJ2132] 圈地计划

Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: 1350  Solved: 637[Submit][Status][Discuss] Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域.GDOI要求将这些区域分为商业区和工业区来开发.根据不同的地形环境,每块小区域建造商业

bzoj2127:最小割

Orz问了师兄好久才懂了,看建图方式就想为什么会对应着三种情况,想流量代表的是什么,后来就画图,果然只有三种情况Orz...所以说要多画图多乱搞... s->(i,j),c=w.代表选理科: (i,j)->t,c=w,代表选文科: 新建k,s->k,c=w,k->(i,j),c=inf,k->(i,j+1),c=inf;代表同时选文或选理:同理. 出现的最小割只会有三种情况,一种是与s相连的都被割掉了,另一种是与t相连的都被割掉了,最后一种是s->k,s->(i,

BZOJ2127 happiness

很好的网络流题目啦,只不过有点烦,不过这下总算是完全掌握了Dinic的精髓... 首先考虑建图: s --> A     权值为a[A] + sigma(他和四周都选全文科的高兴值) / 2 A --> t     权值为b[A] + sigma(他和四周都选全理科的高兴值) / 2 A <--> B  权值为(同时选文科的高兴值+同时选理科的高兴值) / 2 为了解决精度问题,边权先乘以二,最后结果再除以二即可. 但是不知道为什么是对的...在此Orz hzwer,要是没有他的程

【bzoj2127】happiness 网络流最小割

题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大. 输入 第一行两个正整数n,m.接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值.第二个矩阵为n行m列 此矩阵的第i行

【bzoj2132】圈地计划 网络流最小割

题目描述 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域.GDOI要求将这些区域分为商业区和工业区来开发.根据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值.更具体点,对于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益.另外不同的区域连在一起可以得到额外的收益,即如果区域(I,j)相邻(相邻

【BZOJ2132】 圈地计划 最小割

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43201521"); } 题解: 水题,经典模型是两个在一块会损失,显然很好做. 这个同样很好做,就是黑白染色,然后某种颜色该连S集的连T,该连T的连S. 代码: #include <queue> #include <cstdio&g