....最小割,建三列点。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxv 50050 #define maxe 2000050 #define maxn 105 #define inf 1000000007 using namespace std; int n,m,a[maxn][maxn],b[maxn][maxn],c[maxn][maxn],d[maxn][maxn]; int dis[maxv],tot=0,id[maxn][maxn][4],nume=1,g[maxv],sum=0,s,t; struct edge { int v,f,nxt; }e[maxe]; queue <int> q; void addedge(int u,int v,int f) { e[++nume].v=v;e[nume].f=f;e[nume].nxt=g[u];g[u]=nume; e[++nume].v=u;e[nume].f=0;e[nume].nxt=g[v];g[v]=nume; } void build() { s=0;t=++tot; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { addedge(s,id[i][j][1],a[i][j]);addedge(id[i][j][1],t,b[i][j]); addedge(s,id[i][j][2],c[i][j]);addedge(id[i][j][3],t,d[i][j]); addedge(id[i][j][2],id[i][j][1],inf);addedge(id[i][j][1],id[i][j][3],inf); if (i>1) {addedge(id[i-1][j][2],id[i][j][1],inf);addedge(id[i][j][1],id[i-1][j][3],inf);} if (i<n) {addedge(id[i+1][j][2],id[i][j][1],inf);addedge(id[i][j][1],id[i+1][j][3],inf);} if (j>1) {addedge(id[i][j-1][2],id[i][j][1],inf);addedge(id[i][j][1],id[i][j-1][3],inf);} if (j<m) {addedge(id[i][j+1][2],id[i][j][1],inf);addedge(id[i][j][1],id[i][j+1][3],inf);} } } bool bfs() { for (int i=s;i<=t;i++) dis[i]=inf; dis[s]=0;q.push(s); while (!q.empty()) { int head=q.front();q.pop(); for (int i=g[head];i;i=e[i].nxt) { int v=e[i].v; if (dis[v]>dis[head]+1 && e[i].f>0) { dis[v]=dis[head]+1; q.push(v); } } } return dis[t]!=inf; } int dinic(int x,int low) { if (x==t) return low; int ret=0; for (int i=g[x];i && low;i=e[i].nxt) { int v=e[i].v; if (e[i].f>0 && dis[v]==dis[x]+1) { int dd=dinic(v,min(low,e[i].f)); low-=dd;ret+=dd;e[i].f-=dd;e[i^1].f+=dd; } } if (!ret) dis[x]=inf; return ret; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&a[i][j]); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&b[i][j]); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&c[i][j]); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&d[i][j]); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { id[i][j][1]=++tot;id[i][j][2]=++tot;id[i][j][3]=++tot; sum+=a[i][j]+b[i][j]+c[i][j]+d[i][j]; } build(); while (bfs()) sum-=dinic(s,inf); printf("%d\n",sum); return 0; }