A1261. happiness(吴确)[二元组暴力最小割建模]

A1261. happiness(吴确)
时间限制:500ms   内存限制:512.0MB  
总提交次数:158   AC次数:72   平均分:56.71
 
将本题分享到:
      
试题来源
  2011中国国家集训队命题答辩
问题描述
  高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大。
输入格式
  第一行两个正整数n,m。
  接下来是六个矩阵
  第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值。
  第二个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择理科获得的喜悦值。
  第三个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择文科获得的额外喜悦值。
  第四个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择理科获得的额外喜悦值。
  第五个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择文科获得的额外喜悦值。
  第六个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择理科获得的额外喜悦值。
输出格式
  输出一个整数,表示喜悦值总和的最大值
样例输入
1 2
1 1
100 110
1
1000
样例输出
1210
样例说明
  两人都选理,则获得100+110+1000的喜悦值。
数据规模和约定
  对于10%以内的数据,n,m<=4
  对于30%以内的数据,n,m<=8
  对于100%以内的数据,n,m<=100 数据保证答案在2^30以内
  对于100%的数据,时间限制为0.5s。
A1261. happiness(吴确)[二元组暴力最小割建模]

A1261. happiness(吴确)[二元组暴力最小割建模]

A1261. happiness(吴确)[二元组暴力最小割建模]

源代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #define EF if(ch==EOF) return x;
  5. #define rep for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
  6. #define rep1 for(int i=1;i<n;i++)for(int j=1;j<=m;j++)
  7. #define rep2 for(int i=1;i<=n;i++)for(int j=1;j<m;j++)
  8. using namespace std;
  9. const int Z=105;
  10. const int N=Z*Z;
  11. const int M=N*30;
  12. struct edge{int v,next,cap;}e[M<<1];int tot=1,head[N];
  13. int n,m,cnt,res,ans,S,T,dis[N],q[N+M];
  14. int a[Z][Z],b[Z][Z],id[Z][Z];
  15. inline int read(){
  16. int x=0,f=1;char ch=getchar();
  17. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;EF;ch=getchar();}
  18. while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
  19. return x*f;
  20. }
  21. void add(int x,int y,int z){
  22. e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot;
  23. e[++tot].v=x;e[tot].cap=0;e[tot].next=head[y];head[y]=tot;
  24. }
  25. void Add(int x,int y,int z){
  26. e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot;
  27. e[++tot].v=x;e[tot].cap=z;e[tot].next=head[y];head[y]=tot;
  28. }
  29. bool bfs(){
  30. memset(dis,-1,sizeof dis);
  31. int h=0,t=1;q[t]=S;dis[S]=0;
  32. while(h!=t){
  33. int x=q[++h];
  34. for(int i=head[x];i;i=e[i].next){
  35. if(e[i].cap&&dis[e[i].v]==-1){
  36. dis[e[i].v]=dis[x]+1;
  37. if(e[i].v==T) return 1;
  38. q[++t]=e[i].v;
  39. }
  40. }
  41. }
  42. return 0;
  43. }
  44. int dfs(int x,int f){
  45. if(x==T) return f;
  46. int used=0,t;
  47. for(int i=head[x];i;i=e[i].next){
  48. if(e[i].cap&&dis[e[i].v]==dis[x]+1){
  49. t=dfs(e[i].v,min(e[i].cap,f));
  50. e[i].cap-=t;e[i^1].cap+=t;
  51. used+=t;f-=t;
  52. if(!f) return used;
  53. }
  54. }
  55. if(!used) dis[x]=-1;
  56. return used;
  57. }
  58. void dinic(){
  59. res=0;
  60. while(bfs()) res+=dfs(S,2e9);
  61. }
  62. int main(){
  63. n=read();m=read();
  64. rep a[i][j]=read();
  65. rep b[i][j]=read();
  66. rep id[i][j]=++cnt;
  67. S=0;T=cnt+1;
  68. #define u id[i][j]
  69. #define v id[i+1][j]
  70. rep{
  71. add(S,u,b[i][j]<<1);
  72. add(u,T,a[i][j]<<1);
  73. ans+=a[i][j]+b[i][j];
  74. }
  75. rep1 a[i][j]=read();
  76. rep1 b[i][j]=read();
  77. rep1{
  78. add(S,u,b[i][j]);add(S,v,b[i][j]);
  79. add(u,T,a[i][j]);add(v,T,a[i][j]);
  80. Add(u,v,a[i][j]+b[i][j]);
  81. ans+=a[i][j]+b[i][j];
  82. }
  83. #undef v
  84. #define v id[i][j+1]
  85. rep2 a[i][j]=read();
  86. rep2 b[i][j]=read();
  87. rep2{
  88. add(S,u,b[i][j]);add(S,v,b[i][j]);
  89. add(u,T,a[i][j]);add(v,T,a[i][j]);
  90. Add(u,v,a[i][j]+b[i][j]);
  91. ans+=a[i][j]+b[i][j];
  92. }
  93. dinic();
  94. res>>=1;
  95. printf("%d",ans-res);
  96. return 0;
  97. }
上一篇:9.jexus 配置ssl


下一篇:Nginx反向代理的基本配置