bzoj 1001
裸的最小割,直接上Dinic算法。结果跑得很慢。
#include<cstdio> #include<cctype> #include<vector> #include<cstring> #include<algorithm> using namespace std; const int maxn=1000001; const int maxm=6000001; int read(){ char c; while(!isdigit(c=getchar())); int x=c-'0'; while(isdigit(c=getchar())) x=x*10+c-'0'; return x; } struct edge{ int v,c; edge(){} edge(int v,int c):v(v),c(c){} }e[maxm]; vector<int> to[maxn]; int n,m,cnt=0,vis[maxn],dis[maxn],q[maxn]; void add(int u,int v,int c){ e[cnt]=edge(v,c); to[u].push_back(cnt++); } bool bfs(){ memset(vis,0,sizeof vis); vis[1]=1; int h=0,t=0; q[t++]=1; while(h<t){ int fr=q[h++]; for(int i=0;i<to[fr].size();i+=1) if(e[to[fr][i]].c && !vis[e[to[fr][i]].v]){ vis[e[to[fr][i]].v]=1; q[t++]=e[to[fr][i]].v; dis[e[to[fr][i]].v]=dis[fr]+1; } } return vis[n*m]; } int dfs(int o,int f){ if(o==n*m) return f; int res=0; for(int i=0;i<to[o].size() && f;i+=1) if(e[to[o][i]].c && dis[e[to[o][i]].v]==dis[o]+1){ int k=dfs(e[to[o][i]].v,min(f,e[to[o][i]].c)); res+=k; e[to[o][i]].c-=k; e[to[o][i]^1].c+=k; f-=k; } if(!res) dis[o]=-1; return res; } int dinic(){ int ans=0; while(bfs()) ans+=dfs(1,2e9); return ans; } int main(){ n=read(),m=read(); for(int i=1;i<=n;i+=1) for(int j=1;j<m;j+=1){ int c=read(); add((i-1)*m+j,(i-1)*m+j+1,c); add((i-1)*m+j+1,(i-1)*m+j,c); } for(int i=1;i<n;i+=1) for(int j=1;j<=m;j+=1){ int c=read(); add((i-1)*m+j,i*m+j,c); add(i*m+j,(i-1)*m+j,c); } for(int i=1;i<n;i+=1) for(int j=1;j<m;j+=1){ int c=read(); add((i-1)*m+j,i*m+j+1,c); add(i*m+j+1,(i-1)*m+j,c); } printf("%d",dinic()); return 0; }