【BZOJ2127】happiness 网络流
来源:互联网 发布:ubuntu subline 编辑:程序博客网 时间:2024/06/14 00:47
题目描述
有
题解
先把问题简化,考虑只有两个人,甲选文科的喜悦值为
两个人同时选文或同时选理会有额外喜悦值,这并不太好处理。考虑转化一下。先把两人选文的喜悦值
这样就是一个网络流的标准模型了。
最后拿
可以得到以下的网络:
多个人的情况和两个人的情况类似,合在一起处理即可。
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<ctime>#include<utility>#include<cmath>#include<functional>#include<queue>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> pii;typedef pair<ll,ll> pll;void sort(int &a,int &b){ if(a>b) swap(a,b);}void open(const char *s){#ifndef ONLINE_JUDGE char str[100]; sprintf(str,"%s.in",s); freopen(str,"r",stdin); sprintf(str,"%s.out",s); freopen(str,"w",stdout);#endif}int rd(){ int s=0,c; while((c=getchar())<'0'||c>'9'); do { s=s*10+c-'0'; } while((c=getchar())>='0'&&c<='9'); return s;}int upmin(int &a,int b){ if(b<a) { a=b; return 1; } return 0;}int upmax(int &a,int b){ if(b>a) { a=b; return 1; } return 0;}int v[1000010];int w[1000010];int t[1000010];int h[10010];int cnt=0;void add(int x,int y,int z){ cnt++; v[cnt]=y; w[cnt]=z; t[cnt]=h[x]; h[x]=cnt;}int S,T;int d[10010];int e[10010];int cur[10010];int num;int op(int x){ return ((x-1)^1)+1;}queue<int> q;void bfs(){ memset(d,-1,sizeof d); memcpy(cur,h,sizeof h); q.push(T); d[T]=0; int i,x; while(!q.empty()) { x=q.front(); q.pop(); e[d[x]]++; for(i=h[x];i;i=t[i]) if(w[op(i)]&&d[v[i]]==-1) { d[v[i]]=d[x]+1; q.push(v[i]); } }}int dfs(int x,int flow){ if(x==T) return flow; int s=0,c; int &i=cur[x]; for(;i;i=t[i]) if(d[v[i]]==d[x]-1&&w[i]) { c=dfs(v[i],min(flow,w[i])); s+=c; flow-=c; w[i]-=c; w[op(i)]+=c; if(!flow) return s; } e[d[x]]--; if(!e[d[x]]) d[S]=num; e[++d[x]]++; cur[x]=h[x]; return s;}int maxflow(){ bfs(); int ans=0; while(d[S]<=num-1) ans+=dfs(S,0x7fffffff); return ans;}int m1[110][110];int m2[110][110];int m3[110][110];int m4[110][110];int m5[110][110];int m6[110][110];int n,m;int id(int x,int y){ return (x-1)*m+y;}int a1[110][110];int a2[110][110];int a3[110][110];int a4[110][110];int main(){ open("bzoj2127"); scanf("%d%d",&n,&m); int i,j; int sum=0; for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&m1[i][j]); sum+=2*m1[i][j]; a1[i][j]+=2*m1[i][j]; } for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&m2[i][j]); sum+=2*m2[i][j]; a2[i][j]+=2*m2[i][j]; } for(i=1;i<n;i++) for(j=1;j<=m;j++) { scanf("%d",&m3[i][j]); sum+=2*m3[i][j]; a1[i][j]+=m3[i][j]; a1[i+1][j]+=m3[i][j]; a3[i][j]+=m3[i][j]; } for(i=1;i<n;i++) for(j=1;j<=m;j++) { scanf("%d",&m4[i][j]); sum+=2*m4[i][j]; a2[i][j]+=m4[i][j]; a2[i+1][j]+=m4[i][j]; a3[i][j]+=m4[i][j]; } for(i=1;i<=n;i++) for(j=1;j<m;j++) { scanf("%d",&m5[i][j]); sum+=2*m5[i][j]; a1[i][j]+=m5[i][j]; a1[i][j+1]+=m5[i][j]; a4[i][j]+=m5[i][j]; } for(i=1;i<=n;i++) for(j=1;j<m;j++) { scanf("%d",&m6[i][j]); sum+=2*m6[i][j]; a2[i][j]+=m6[i][j]; a2[i][j+1]+=m6[i][j]; a4[i][j]+=m6[i][j]; } num=n*m+2; S=n*m+1; T=n*m+2; for(i=1;i<=n;i++) for(j=1;j<=m;j++) { add(S,id(i,j),a1[i][j]); add(id(i,j),S,0); add(id(i,j),T,a2[i][j]); add(T,id(i,j),0); } for(i=1;i<n;i++) for(j=1;j<=m;j++) { add(id(i,j),id(i+1,j),a3[i][j]); add(id(i+1,j),id(i,j),a3[i][j]); } for(i=1;i<=n;i++) for(j=1;j<m;j++) { add(id(i,j),id(i,j+1),a4[i][j]); add(id(i,j+1),id(i,j),a4[i][j]); } int ans=maxflow(); ans=sum-ans; ans>>=1; printf("%d\n",ans); return 0;}
阅读全文
0 0
- 【BZOJ2127】happiness 网络流
- [BZOJ2127]happiness(网络流)
- 【BZOJ2127】happiness(网络流dinic)
- bzoj2127 happiness
- bzoj2127: happiness
- bzoj2127 happiness
- BZOJ2127: happiness
- bzoj2127 happiness
- 【bzoj2127】happiness
- bzoj2127 happiness
- bzoj2127 happiness
- bzoj2127: happiness 最小割
- 【bzoj2127】happiness 最小割
- bzoj2127 happiness 最小割
- BZOJ2127 happiness-最小割
- [bzoj2127] happiness 最小割
- bzoj2127 happiness(最小割)
- 【BZOJ2127】happiness 最小割 自己YY出来的建图、
- [沉思录(中英双语)·典藏本].(古罗马)奥勒留.扫描版.PDF 免费下载
- 赋值类型中的自动转换
- with...as
- LeetCode 70. Climbing Stairs 动态规划
- 函数返回类型和形参
- 【BZOJ2127】happiness 网络流
- Latex常用命令
- 泛型DAO
- Ubuntu更新vim编辑器,及vi常用命令
- Diffie-Hellman
- JAVA并发编程之volatile变量应用详解
- 编辑一个带有“文件”的窗体
- java方法和内存空间
- 关于OpenCV Mat读取像素值