bzoj 1001
没有什么是一个BFS或一个DFS解决不了的;如果有,那就两个一起。
裸的最小割,dinic算法水过。
注意时间比较紧,要加一些优化,比如到不了T的边就把它的dis赋值为0。
#include<cstdio> #include<cctype> #include<cstring> #include<algorithm> using namespace std; const int maxn=1000001,maxe=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[maxe]; int now=0,hed[maxn],nex[maxe]; void add(int u,int v,int c){ e[++now]=edge(v,c); nex[now]=hed[u]; hed[u]=now; } int q[maxn],d[maxn]; int bfs(int n,int m){ int h=0,t=0; memset(d,0,sizeof d); q[t++]=1; d[1]=1; while(h<t){ int fr=q[h++]; for(int i=hed[fr];i!=-1;i=nex[i]) if(e[i].c>0 && !d[e[i].v]) d[e[i].v]=d[fr]+1,q[t++]=e[i].v; } return d[n*m]; } int dfs(int o,int n,int m,int w){ if(o==n*m) return w; int t=0; for(int i=hed[o];i!=-1 && w;i=nex[i]) if(e[i].c>0 && d[e[i].v]==d[o]+1){ int k=dfs(e[i].v,n,m,min(w,e[i].c)); w-=k; e[i].c-=k; t+=k; e[i^1].c+=k; } if(!t) d[o]=0; return t; } int dinic(int n,int m){ int ans=0; while(bfs(n,m)) ans+=dfs(1,n,m,2e9); return ans; } int main(){ memset(hed,-1,sizeof hed); int 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(n,m)); return 0; }