...
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxn 35 #define maxv 1050 #define maxe 500500 #define inf 1000000007 using namespace std; int n,a[maxn][maxn],g[maxv],nume=1,sum=0,max_flow=0,dis[maxv],s,t; int dx[]={0,1,0,-1,0},dy[]={0,0,1,0,-1}; struct edge { int v,f,nxt; }e[maxe]; queue <int> q; int f(int x,int y) {return (x-1)*n+y;} bool judge(int x,int y) { return ((x>=1) && (x<=n) && (y>=1) && (y<=n)); } 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; } bool bfs() { while (!q.empty()) q.pop(); 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 (e[i].f<=0) continue; if (dis[v]>dis[head]+1) { 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];low && i;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)); e[i].f-=dd;e[i^1].f+=dd; ret+=dd;low-=dd; } } if (!ret) dis[x]=inf; return ret; } int main() { scanf("%d",&n);s=0;t=n*n+1; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { scanf("%d",&a[i][j]);sum+=a[i][j]; if ((i+j)&1) addedge(s,f(i,j),a[i][j]); else addedge(f(i,j),t,a[i][j]); } for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) { if (!((i+j)&1)) continue; for (int k=1;k<=4;k++) { int tx=i+dx[k],ty=j+dy[k]; if (judge(tx,ty)) addedge(f(i,j),f(tx,ty),inf); } } while (bfs()) max_flow+=dinic(s,inf); printf("%d\n",sum-max_flow); return 0; }