把所有的边建出来后跑最小割,题目是最小割并不难理解
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<queue> 5 #define M 1000009 6 using namespace std; 7 int head[M],next[6*M],v[6*M],u[6*M],n,m,cnt=1,ans,d[M]; 8 void jia(int a1,int a2,int a3) 9 { 10 cnt++; 11 v[cnt]=a3; 12 u[cnt]=a2; 13 next[cnt]=head[a1]; 14 head[a1]=cnt; 15 } 16 bool bfs() 17 { 18 memset(d,0,sizeof(d)); 19 queue<int> q; 20 q.push(1); 21 d[1]=1; 22 for(;!q.empty();) 23 { 24 int now=q.front(); 25 q.pop(); 26 for(int i=head[now];i;i=next[i]) 27 if(v[i]&&!d[u[i]]) 28 { 29 q.push(u[i]); 30 d[u[i]]=d[now]+1; 31 if(u[i]==n*m) 32 return 1; 33 } 34 } 35 return 0; 36 } 37 int dinic(int x,int f) 38 { 39 if(x==n*m) 40 return f; 41 int rest=f,now; 42 for(int i=head[x];i;i=next[i]) 43 if(v[i]&&d[u[i]]==d[x]+1&&rest) 44 { 45 now=dinic(u[i],min(rest,v[i])); 46 if(!now) 47 d[u[i]]=0; 48 v[i]-=now; 49 v[i^1]+=now; 50 rest-=now; 51 } 52 return f-rest; 53 } 54 int main() 55 { 56 scanf("%d%d",&n,&m); 57 for(int i=1;i<=n;i++) 58 for(int j=1;j<m;j++) 59 { 60 int a1; 61 scanf("%d",&a1); 62 jia((i-1)*m+j,(i-1)*m+j+1,a1); 63 jia((i-1)*m+j+1,(i-1)*m+j,a1); 64 } 65 for(int i=1;i<n;i++) 66 for(int j=1;j<=m;j++) 67 { 68 int a1; 69 scanf("%d",&a1); 70 jia((i-1)*m+j,i*m+j,a1); 71 jia(i*m+j,(i-1)*m+j,a1); 72 } 73 for(int i=1;i<n;i++) 74 for(int j=1;j<m;j++) 75 { 76 int a1; 77 scanf("%d",&a1); 78 jia((i-1)*m+j,i*m+j+1,a1); 79 jia(i*m+j+1,(i-1)*m+j,a1); 80 } 81 for(;bfs();) 82 ans+=dinic(1,0x7fffffff); 83 printf("%d\n",ans); 84 return 0; 85 }