题解:
最小割
跑一下网络流
代码:
#include<bits/stdc++.h> using namespace std; const int N=1000005; struct data{int to,next,v;}e[N*6]; int fi[N],n,m,num,h[N],q[N],ans; void jb(int x,int y,int z) { e[++num].to=y; e[num].v=z; e[num].next=fi[x]; fi[x]=num; } int bfs() { memset(h,-1,sizeof(h)); int t=0,w=1; q[t]=1;h[1]=0; while (t<w) { int now=q[t++]; for (int i=fi[now];i;i=e[i].next) if (e[i].v&&h[e[i].to]<0) { q[w++]=e[i].to; h[e[i].to]=h[now]+1; } } if (h[n*m]==-1)return 0; return 1; } int dfs(int x,int f) { if(x==n*m)return f; int w,used=0; for (int i=fi[x];i;i=e[i].next) if (e[i].v&&h[e[i].to]==h[x]+1) { w=f-used; w=dfs(e[i].to,min(w,e[i].v)); e[i].v-=w; e[i+1].v+=w; used+=w; if (used==f)return f; } if (!used)h[x]=-1; return used; } void dinic() { while(bfs())ans+=dfs(1,0x7fffffff); } int main() { scanf("%d%d",&n,&m); int x; for (int i=1;i<=n;i++) for (int j=1;j<m;j++) { scanf("%d",&x); jb(m*(i-1)+j,m*(i-1)+j+1,x); jb(m*(i-1)+j+1,m*(i-1)+j,x); } for (int i=1;i<n;i++) for (int j=1;j<=m;j++) { scanf("%d",&x); jb(m*(i-1)+j,m*(i)+j,x); jb(m*(i)+j,m*(i-1)+j,x); } for (int i=1;i<n;i++) for (int j=1;j<m;j++) { scanf("%d",&x); jb(m*(i-1)+j,m*(i)+j+1,x); jb(m*(i)+j+1,m*(i-1)+j,x); } dinic(); printf("%d",ans); return 0; }