码迷,mamicode.com
首页 > 移动开发 > 详细

Bzoj2127 happiness

时间:2017-01-23 21:21:37      阅读:265      评论:0      收藏:0      [点我收藏+]

标签:自己   insert   i+1   计算   init   algorithm   最小割   iostream   logs   

Time Limit: 51 Sec  Memory Limit: 259 MB
Submit: 1869  Solved: 912

Description

高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大。

Input

第一行两个正整数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列的同学同时选择理科获得的额外喜悦值。

Output

输出一个整数,表示喜悦值总和的最大值

Sample Input

1 2
1 1
100 110
1
1000

Sample Output

1210
【样例说明】
两人都选理,则获得100+110+1000的喜悦值。
【数据规模】
对于100%以内的数据,n,m<=100 所有喜悦值均为小于等于5000的非负整数

HINT

 

Source

 

网络流最小割

 

  1 /*by SilverN*/
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<vector>
  8 #include<queue>
  9 using namespace std;
 10 const int mx[5]={0,1,0,-1,0};
 11 const int my[5]={0,0,1,0,-1};
 12 const int INF=1e9;
 13 const int mxn=20010;
 14 int read(){
 15     int x=0,f=1;char ch=getchar();
 16     while(ch<0 || ch>9){if(ch==-)f=-1;ch=getchar();}
 17     while(ch>=0 && ch<=9){x=x*10+ch-0;ch=getchar();}
 18     return x*f;
 19 }
 20 struct edge{
 21     int v,nxt,f;
 22 }e[mxn*50];
 23 int hd[mxn],mct=1;
 24 void add_edge(int u,int v,int f){
 25     e[++mct].v=v;e[mct].nxt=hd[u];e[mct].f=f;hd[u]=mct;return;
 26 }
 27 void insert(int u,int v,int f){
 28     add_edge(u,v,f);
 29     add_edge(v,u,0);
 30     return;
 31 }
 32 int n,m,S,T;
 33 int d[mxn];
 34 bool BFS(){
 35     memset(d,0,sizeof d);
 36     queue<int>q;
 37     d[S]=1;
 38     q.push(S);
 39     while(!q.empty()){
 40         int u=q.front();q.pop();
 41         for(int i=hd[u];i;i=e[i].nxt){
 42             int v=e[i].v;
 43             if(e[i].f && !d[v]){
 44                 d[v]=d[u]+1;
 45                 q.push(v);
 46             }
 47         }
 48     }
 49     return d[T];
 50 }
 51 int DFS(int u,int lim){
 52     if(u==T)return lim;
 53     int f=0,tmp;
 54     for(int i=hd[u];i;i=e[i].nxt){
 55         int v=e[i].v;
 56         if(d[v]==d[u]+1 && e[i].f && (tmp=DFS(v,min(lim,e[i].f)))){
 57             e[i].f-=tmp;
 58             e[i^1].f+=tmp;
 59             f+=tmp;
 60             lim-=tmp;
 61             if(!lim)return f;
 62         }
 63     }
 64     d[u]=0;
 65     return f;
 66 }
 67 int Dinic(){
 68     int res=0;
 69     while(BFS())res+=DFS(S,INF);
 70     return res;
 71 }
 72 int id[110][110],cnt=0,ed;
 73 void init(){
 74     for(int i=1;i<=n;i++)
 75      for(int j=1;j<=m;j++)
 76          id[i][j]=++cnt;
 77     ed=n*m;
 78     return;
 79 }
 80 int ans=0;
 81 int A[mxn],Si[mxn];
 82 void solve(){
 83     int i,j,x;
 84     int smm=0;
 85     for(i=1;i<=n;i++)
 86         for(j=1;j<=m;j++){
 87             x=read();
 88             A[id[i][j]]=x*2,smm+=x;
 89     }
 90     for(i=1;i<=n;i++)
 91         for(j=1;j<=m;j++){
 92             x=read();
 93             Si[id[i][j]]=x*2,smm+=x;
 94     }
 95     for(i=1;i<n;i++)
 96         for(j=1;j<=m;j++){
 97             x=read();smm+=x;
 98             add_edge(id[i][j],id[i+1][j],x);
 99             add_edge(id[i+1][j],id[i][j],x);
100             A[id[i][j]]+=x;
101             A[id[i+1][j]]+=x;
102         }
103     for(i=1;i<n;i++)
104         for(j=1;j<=m;j++){
105             x=read();smm+=x;
106             add_edge(id[i][j],id[i+1][j],x);
107             add_edge(id[i+1][j],id[i][j],x);
108             Si[id[i][j]]+=x;
109             Si[id[i+1][j]]+=x;
110         }
111     for(i=1;i<=n;i++)
112         for(j=1;j<m;j++){
113             x=read();smm+=x;
114             add_edge(id[i][j],id[i][j+1],x);
115             add_edge(id[i][j+1],id[i][j],x);
116             A[id[i][j]]+=x;
117             A[id[i][j+1]]+=x;
118         }
119     for(i=1;i<=n;i++)
120         for(j=1;j<m;j++){
121             x=read();smm+=x;
122             add_edge(id[i][j],id[i][j+1],x);
123             add_edge(id[i][j+1],id[i][j],x);
124             Si[id[i][j]]+=x;
125             Si[id[i][j+1]]+=x;
126         }
127     for(i=1;i<=n;i++)
128         for(j=1;j<=m;j++){
129             insert(S,id[i][j],A[id[i][j]]);
130             insert(id[i][j],T,Si[id[i][j]]);
131         }
132     ans=smm-Dinic()/2;
133     return;
134 }
135 int main(){
136     int i,j,x;
137     n=read();m=read();
138     S=0;T=n*m+1;
139     init();
140     solve();
141     printf("%d\n",ans);
142     return 0;
143 }

 

Bzoj2127 happiness

标签:自己   insert   i+1   计算   init   algorithm   最小割   iostream   logs   

原文地址:http://www.cnblogs.com/SilverNebula/p/6344911.html

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