1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define M 100009 5 #define inf 2139062143 6 using namespace std; 7 int n,m,a[102][102],b[102][102],c[102][102],tot,cnt=1,T,ans,head[M],d[M],q[2*M],next[10*M],u[10*M],v[10*M]; 8 int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0}; 9 bool bfs() 10 { 11 memset(d,0,sizeof(int)*(T+1)); 12 int h=0,t=1; 13 q[1]=0; 14 d[0]=1; 15 for(;h<t;) 16 { 17 h++; 18 int p=q[h]; 19 for(int i=head[p];i;i=next[i]) 20 if(!d[u[i]]&&v[i]) 21 { 22 d[u[i]]=d[p]+1; 23 if(d[T]) 24 return 1; 25 t++; 26 q[t]=u[i]; 27 } 28 } 29 return 0; 30 } 31 int dinic(int s,int f) 32 { 33 if(s==T) 34 return f; 35 int rest=f; 36 for(int i=head[s];i&&rest;i=next[i]) 37 if(v[i]&&d[u[i]]==d[s]+1) 38 { 39 int now=dinic(u[i],min(rest,v[i])); 40 if(!now) 41 d[u[i]]=0; 42 v[i]-=now; 43 v[i^1]+=now; 44 rest-=now; 45 } 46 return f-rest; 47 } 48 void jia1(int a1,int a2,int a3) 49 { 50 cnt++; 51 next[cnt]=head[a1]; 52 head[a1]=cnt; 53 u[cnt]=a2; 54 v[cnt]=a3; 55 return; 56 } 57 void jia(int a1,int a2,int a3) 58 { 59 jia1(a1,a2,a3); 60 jia1(a2,a1,0); 61 tot+=a3; 62 return; 63 } 64 int main() 65 { 66 scanf("%d%d",&n,&m); 67 T=n*m+1; 68 for(int i=1;i<=n;i++) 69 for(int j=1;j<=m;j++) 70 scanf("%d",&a[i][j]); 71 for(int i=1;i<=n;i++) 72 for(int j=1;j<=m;j++) 73 scanf("%d",&b[i][j]); 74 for(int i=1;i<=n;i++) 75 for(int j=1;j<=m;j++) 76 scanf("%d",&c[i][j]); 77 for(int i=1;i<=n;i++) 78 for(int j=1;j<=m;j++) 79 { 80 if((i+j)&1) 81 swap(a[i][j],b[i][j]); 82 jia(0,(i-1)*m+j,a[i][j]); 83 jia((i-1)*m+j,T,b[i][j]); 84 for(int k=0;k<4;k++) 85 { 86 int nx=i+xx[k],ny=j+yy[k]; 87 if(!nx||!ny||nx>n||ny>m) 88 continue; 89 jia((i-1)*m+j,(nx-1)*m+ny,c[i][j]+c[nx][ny]); 90 tot-=c[i][j]; 91 } 92 } 93 for(;bfs();) 94 ans+=dinic(0,inf); 95 printf("%d\n",tot-ans); 96 return 0; 97 }
将图黑白染色 S向i(黑点)连边容量为农,S向j(白点)连边容量为工,i向T连边容量为工,j向T连边容量为农,i与j连边容量为混合收益。