[bzoj2127]happiness
同[bzoj3894]文理分科,只是将五个点一组改为2个点一组(另外还可以通过解方程优化建边,但这里不需要)。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 60005 4 #define id (i-1)*m+j 5 #define inf 0x3f3f3f3f 6 struct ji{ 7 int nex,to,len; 8 }edge[N*7]; 9 queue<int>q; 10 int E,n,m,k,ans,d[N],head[N],work[N]; 11 void add(int x,int y,int z){ 12 edge[E].nex=head[x]; 13 edge[E].to=y; 14 edge[E].len=z; 15 head[x]=E++; 16 if (E&1)add(y,x,0); 17 } 18 bool bfs(){ 19 q.push(0); 20 memset(d,-1,sizeof(d)); 21 d[0]=0; 22 while (!q.empty()){ 23 int k=q.front(); 24 q.pop(); 25 for(int i=head[k];i!=-1;i=edge[i].nex) 26 if ((edge[i].len)&&(d[edge[i].to]<0)){ 27 d[edge[i].to]=d[k]+1; 28 q.push(edge[i].to); 29 } 30 } 31 return d[n]>=0; 32 } 33 int dfs(int k,int s){ 34 if (k==n)return s; 35 int p; 36 for(int &i=work[k];i!=-1;i=edge[i].nex) 37 if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){ 38 p=dfs(edge[i].to,min(s,edge[i].len)); 39 if (p){ 40 edge[i].len-=p; 41 edge[i^1].len+=p; 42 return p; 43 } 44 } 45 return 0; 46 } 47 int dinic(){ 48 int k,ans=0; 49 while (bfs()){ 50 memcpy(work,head,sizeof(work)); 51 while (k=dfs(0,inf))ans+=k; 52 } 53 return ans; 54 } 55 int main(){ 56 scanf("%d%d",&n,&m); 57 memset(head,-1,sizeof(head)); 58 for(int i=1;i<=n;i++) 59 for(int j=1;j<=m;j++){ 60 scanf("%d",&k); 61 add(0,id,k); 62 ans+=k; 63 } 64 for(int i=1;i<=n;i++) 65 for(int j=1;j<=m;j++){ 66 scanf("%d",&k); 67 add(id,5*n*m+1,k); 68 ans+=k; 69 } 70 for(int i=1;i<n;i++) 71 for(int j=1;j<=m;j++){ 72 scanf("%d",&k); 73 add(0,n*m+id,k); 74 add(n*m+id,id,inf); 75 add(n*m+id,id+m,inf); 76 ans+=k; 77 } 78 for(int i=1;i<n;i++) 79 for(int j=1;j<=m;j++){ 80 scanf("%d",&k); 81 add(2*n*m+id,5*n*m+1,k); 82 add(id,2*n*m+id,inf); 83 add(id+m,2*n*m+id,inf); 84 ans+=k; 85 } 86 for(int i=1;i<=n;i++) 87 for(int j=1;j<m;j++){ 88 scanf("%d",&k); 89 add(0,3*n*m+id,k); 90 add(3*n*m+id,id,inf); 91 add(3*n*m+id,id+1,inf); 92 ans+=k; 93 } 94 for(int i=1;i<=n;i++) 95 for(int j=1;j<m;j++){ 96 scanf("%d",&k); 97 add(4*n*m+id,5*n*m+1,k); 98 add(id,4*n*m+id,inf); 99 add(id+1,4*n*m+id,inf); 100 ans+=k; 101 } 102 n=5*n*m+1; 103 printf("%d",ans-dinic()); 104 }