【题目分析】
基本上是第一次真正的使用最小割的模型。
同时加上一个数然后最后再减去是处理负数的一种方法。
设立出来最小割的模型然后解方程是一件很重要的事情,建议取一个相对来说比较简单的值带入求解。
这道题目,把收益取反,最小流就是最大的收益了。
需要好好思考
【代码】
#include <cstdio> #include <cstring> //#include <cmath> //#include <cstdlib> //#include <map> //#include <set> #include <queue> //#include <string> //#include <iostream> //#include <algorithm> using namespace std; #define maxn 105 #define maxn2 105*105 #define me 800005 #define inf 0x3f3f3f3f #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) void Finout() { #ifndef ONLINE_JUDGE freopen("nt2011_happiness.in","r",stdin); freopen("nt2011_happiness.out","w",stdout); #endif } int Getint() { int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } int h[me<<1],to[me<<1],ne[me<<1],fl[me<<1],en=0,cnt=0,S=0,T,x; void add(int a,int b,int c) {to[en]=b; ne[en]=h[a]; fl[en]=c; h[a]=en++;} int map[maxn*maxn]; bool tell() { queue <int> q; memset(map,-1,sizeof map); map[S]=0; while (!q.empty()) q.pop(); q.push(S); while (!q.empty()) { int x=q.front(); q.pop(); for (int i=h[x];i>=0;i=ne[i]) { if (map[to[i]]==-1&&fl[i]>0) { map[to[i]]=map[x]+1; q.push(to[i]); } } } if (map[T]!=-1) return true; return false; } int zeng(int k,int r) { if (k==T) return r; int ret=0; for (int i=h[k];i>=0&&ret<r;i=ne[i]) if (map[to[i]]==map[k]+1&&fl[i]>0) { int tmp=zeng(to[i],min(fl[i],r-ret)); ret+=tmp; fl[i]-=tmp; fl[i^1]+=tmp; } if (!ret) map[k]=-1; return ret; } int n,m,hash[maxn][maxn],ws[maxn2]; int wt[maxn2],all=0; int main() { memset(h,-1,sizeof h); Finout(); n=Getint(); m=Getint(); F(i,1,n) F(j,1,m) hash[i][j]=++cnt; // F(i,1,n) // { // F(j,1,m) printf("%d ",hash[i][j]); // printf(" "); // } T=++cnt; F(i,1,n) F(j,1,m) { x=Getint(); all+=x; wt[hash[i][j]]+=2*x; } F(i,1,n) F(j,1,m) { x=Getint(); all+=x; ws[hash[i][j]]+=2*x; } F(i,1,n-1) F(j,1,m) { x=Getint(); all+=x; wt[hash[i][j]]+=x; wt[hash[i+1][j]]+=x; add(hash[i][j],hash[i+1][j],x); add(hash[i+1][j],hash[i][j],x); } F(i,1,n-1) F(j,1,m) { x=Getint(); all+=x; ws[hash[i][j]]+=x; ws[hash[i+1][j]]+=x; add(hash[i][j],hash[i+1][j],x); add(hash[i+1][j],hash[i][j],x); } F(i,1,n) F(j,1,m-1) { x=Getint(); all+=x; wt[hash[i][j]]+=x; wt[hash[i][j+1]]+=x; add(hash[i][j],hash[i][j+1],x); add(hash[i][j+1],hash[i][j],x); } F(i,1,n) F(j,1,m-1) { x=Getint(); all+=x; ws[hash[i][j]]+=x; ws[hash[i][j+1]]+=x; add(hash[i][j],hash[i][j+1],x); add(hash[i][j+1],hash[i][j],x); } // printf("over! "); F(i,1,n) F(j,1,m) { add(S,hash[i][j],ws[hash[i][j]]); add(hash[i][j],S,0); add(hash[i][j],T,wt[hash[i][j]]); add(T,hash[i][j],0); } int ans=0,tmp; while (tell()) while (tmp=zeng(S,inf)) ans+=tmp; printf("%d ",all-ans/2); }