luogu P4313 文理分科 網路流最小割模型
阿新 • • 發佈:2020-10-28
https://www.luogu.com.cn/blog/CJL/solution-p4313
#include<iostream> #include<cstring> using namespace std; const int N=400020; #define int long long const int INF=1e9; int n,m,S,T; int h[N],e[N],ne[N],idx,w[N]; int q[N],d[N],cur[N]; void add(int a,int b,int c) { e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++; e[idx]=a,w[idx]=0,ne[idx]=h[b],h[b]=idx++; } bool bfs() { int hh=0; int tt=0; memset(d,-1,sizeof d); q[0]=S; d[S]=0; cur[S]=h[S]; while(hh<=tt) { int t=q[hh++]; for(int i=h[t]; i!=-1; i=ne[i]) { int ver=e[i]; if(d[ver]==-1&&w[i]) { d[ver]=d[t]+1; cur[ver]=h[ver]; if(ver==T) return true; q[++tt]=ver; } } } return false; } int find(int u,int limit) { if(u==T) return limit; int flow=0; for(int i=cur[u]; ~i&&flow<limit; i=ne[i]) { cur[u]=i; int ver=e[i]; if(d[ver]==d[u]+1&&w[i]) { int t=find(ver,min(w[i],limit-flow)); if(!t) d[ver]=-1; w[i]-=t; w[i^1]+=t; flow+=t; } } return flow; } int dinic() { int r=0; int flow; while(bfs()) while(flow=find(S,INF)) r+=flow; return r; } int get(int i,int j) { return (i-1)*m+j; } bool check(int x,int y) { return x>=1&&x<=n&&y>=1&&y<=m; } signed main() { memset(h,-1,sizeof h); cin>>n>>m; int tot=n*m; S=0,T=++tot; int sum=0; for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) { int x; cin>>x; sum+=x; add(S,get(i,j),x); } for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) { int x; cin>>x; sum+=x; add(get(i,j),T,x); } for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) { int x; cin>>x; sum+=x; add(S,++tot,x); add(tot,get(i,j),INF); if(check(i-1,j)) add(tot,get(i-1,j),INF); if(check(i,j-1)) add(tot,get(i,j-1),INF); if(check(i+1,j)) add(tot,get(i+1,j),INF); if(check(i,j+1)) add(tot,get(i,j+1),INF); } for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) { int x; cin>>x; sum+=x; add(++tot,T,x); add(get(i,j),tot,INF); if(check(i-1,j)) add(get(i-1,j),tot,INF); if(check(i+1,j)) add(get(i+1,j),tot,INF); if(check(i,j+1)) add(get(i,j+1),tot,INF); if(check(i,j-1)) add(get(i,j-1),tot,INF); } cout<<sum-dinic()<<endl; }