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连边容量为混合收益。

posted on 2016-03-20 15:30  xiyuedong  阅读(174)  评论(0编辑  收藏  举报