码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2127&bzoj2132

时间:2016-03-27 17:37:45      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

题目: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 }
View Code

 

技术分享
 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 }
View Code

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

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

利用最小割考虑。

对于原图中所有相邻的两个人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就行。

bzoj2127&bzoj2132

标签:

原文地址:http://www.cnblogs.com/YuanZiming/p/5326026.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!