BZOJ 2127 : happiness 疯了的最小割
2018-03-24 15:32
751 查看
BZOJ 2127 : happiness 疯了的最小割
题目传送门PS:幸好,先做了 阿狸和桃子的游戏 那一题,不然,想的脑壳teng。
【问题描述】
一群人选文理科,每人选文选里都有收益,相邻两个人同时选文和选理也有收益。最大化收益。
【解题思路】
选文选理,二选一。把所有的收益加起来,减去尽可能少的损失。
看起来像是网络流-最小割(其实就是)
参考bzoj2563阿狸和桃子的游戏
把边的权值,试图把边的权值分离在点上
就成了这样。。
两者不选文,则把文的都割掉。
两者不选理,则把理的都割掉。
那一边割理一边割文的怎么办?
那就再造一条val[文][AB]/2+val[理][AB]/2的边(图中双杠的边,把它也割掉)。反之亦然
最后成了这样。。
其实呢,这个图还是可以化简的(从黄学长那里看来的,简洁,cool~~~~~~~~~~)
完结,撒花~~~
【代码】
#include<bits/stdc++.h> #define imax(a,b) ((a>b)?(a):(b)) #define imin(a,b) ((a<b)?(a):(b)) using namespace std; typedef long long ll; const int N=120; const int M=300050; int S,T,sum,n,m; int P ; int ne[M],to[M],val[M],h[M],tt; int d [2],g [2],s [2]; int q[M],bfstime; int vis[M],lev[M]; void read(int &x) { x=0; char ch=getchar(); int f=1; for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(; isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-'0'; x*=f; } void addedge(int a,int b,int c) { to[++tt]=b; ne[tt]=h[a]; h[a]=tt; val[tt]=c; } void addgo(int a,int b,int c) { addedge(a,b,c); addedge(b,a,0); } bool bfs() { int head=1,tail=1; q[head]=S; vis[S]=++bfstime; lev[S]=1; while(head<=tail) { for(int p=h[q[head]];p;p=ne[p]) { if(!val[p]) continue; if(vis[to[p]]==bfstime) continue; q[++tail]=to[p]; vis[to[p]]=bfstime; lev[to[p]]=lev[q[head]]+1; } head++; } return vis[T]==bfstime; } int dfs(int now,int maxf) { int ret=0,t; if(now==T || !maxf ) return maxf; for(int p=h[now];p;p=ne[p]) { if(!val[p] || lev[to[p]]!=lev[now]+1) continue; t=dfs(to[p],imin(maxf,val[p])); val[p]-=t; val[p^1]+=t; maxf-=t; ret+=t; } if(maxf) lev[now]=-1; return ret; } int dinic() { int ret=0; while(bfs()) ret+=dfs(S,1e9); return ret; } void init() { read(n); read(m); tt=1; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) P[i][j]=(i-1)*m+j+1; S=P [m]+1; T=S+1; for(int o=0;o<2;o++) for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) read(d[i][j][o]),sum+=d[i][j][o],d[i][j][o]<<=1; for(int o=0;o<2;o++) for(int i=1;i<n;i++) for(int j=1;j<=m;j++) read(g[i][j][o]),sum+=g[i][j][o]; for(int o=0;o<2;o++) for(int i=1;i<=n;i++) for(int j=1;j<m;j++) read(s[i][j][o]),sum+=s[i][j][o]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { addgo(S,P[i][j],d[i][j][0]+g[i][j][0]+g[i-1][j][0]+s[i][j][0]+s[i][j-1][0]); addgo(P[i][j],T,d[i][j][1]+g[i][j][1]+g[i-1][j][1]+s[i][j][1]+s[i][j-1][1]); if(i!=n) { addgo(P[i][j],P[i+1][j],g[i][j][0]+g[i][j][1]); addgo(P[i+1][j],P[i][j],g[i][j][0]+g[i][j][1]); } if(j!=m) { addgo(P[i][j],P[i][j+1],s[i][j][0]+s[i][j][1]); addgo(P[i][j+1],P[i][j],s[i][j][0]+s[i][j][1]); } } } int main() { init(); printf("%d\n",sum-(dinic()>>1)); return 0; }
相关文章推荐
- [bzoj2127][网络流-最小割]happiness
- 【BZOJ2127】happiness 最小割 自己YY出来的建图、
- [置顶] [BZOJ]2127: happiness 最小割
- bzoj 2127 happiness(最小割)
- BZOJ_3894_文理分科&&BZOJ_2127_happiness_最小割
- [JZOJ1919] [BZOJ2127]【2011集训队出题】happiness(最小割之二元关系)
- BZOJ2127 happiness-最小割
- BZOJ 2127: happiness(最小割)
- BZOJ 2127: happiness 最小割 二元组建图
- BZOJ 2127 Happiness 最小割
- 【 bzoj 2127 】happiness - 最小割
- BZOJ 2127: happiness(最小割解决集合划分)
- BZOJ2127 happiness-最小割
- BZOJ 2127: happiness [最小割]
- [BZOJ 2127] happiness 【最小割】
- BZOJ 2127 happiness 最小割
- 【bzoj2127】happiness 最小割
- BZOJ 2127: happiness( 最小割 )
- 【BZOJ2127】happiness 最小割
- 【bzoj2127】happiness 网络流最小割