BZOJ3511 土地劃分
阿新 • • 發佈:2019-01-31
一眼最小割
考慮劃為S集代表A國,劃為T集代表B國
建圖:S連每個點流量VA,每個點連T流量VB
對於每條邊,兩個端點點之間連雙向邊流量EC
新建一個點X,S連X流量EA,X連兩個端點流量INF
再新建一個點Y,兩個端點連Y流量INF,Y連T流量EB
認為1號點VA=INF,VB=0
n號點VA=0,VB=INF
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> #include<iomanip> #include<vector> #include<map> #include<set> #include<bitset> #include<queue> #include<stack> using namespace std; #define MAXN 100010 #define MAXM 4000010 #define INF 1000000000 #define MOD 1000000007 #define eps 1e-8 #define ll long long struct vec{ int to; int fro; int v; }; vec mp[MAXM]; int tai[MAXN],cnt=1; int q[MAXN],hd,tl; int d[MAXN]; int s,t; int ans; inline void be(int x,int y,int z){ mp[++cnt].to=y; mp[cnt].fro=tai[x]; tai[x]=cnt; mp[cnt].v=z; } inline void bse(int x,int y,int z){ be(x,y,z); be(y,x,0); } inline void bde(int x,int y,int z){ be(x,y,z); be(y,x,z); } int bfs(){ int i,x,y; memset(d,0,sizeof(d)); hd=tl=0; d[s]=1; q[tl++]=s; while(hd!=tl){ x=q[hd++]; for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(!d[y]&&mp[i].v){ d[y]=d[x]+1; q[tl++]=y; } } } return d[t]; } int dfs(int x,int mx){ if(x==t){ return mx; } int i,y,re=0,tmp; for(i=tai[x];i;i=mp[i].fro){ y=mp[i].to; if(d[y]==d[x]+1&&mp[i].v){ tmp=dfs(y,min(mp[i].v,mx)); re+=tmp; mx-=tmp; mp[i].v-=tmp; mp[i^1].v+=tmp; if(!mx){ return re; } } } if(!re){ d[x]=0; } return re; } int n,m,tot; int main(){ int i,x,y,z; scanf("%d%d",&n,&m); s=n+1; t=s+1; tot=t; ans+=INF*2; bse(s,1,INF); bse(n,t,INF); for(i=2;i<n;i++){ scanf("%d",&x); bse(s,i,x); ans+=x; } for(i=2;i<n;i++){ scanf("%d",&x); bse(i,t,x); ans+=x; } for(i=1;i<=m;i++){ scanf("%d%d",&x,&y); scanf("%d",&z); ans+=z; tot++; bse(tot,x,INF); bse(tot,y,INF); bse(s,tot,z); scanf("%d",&z); ans+=z; tot++; bse(x,tot,INF); bse(y,tot,INF); bse(tot,t,z); scanf("%d",&z); bde(x,y,z); } while(bfs()){ ans-=dfs(s,INF); } printf("%d\n",ans-INF*2); return 0; } /* 3 3 8 9 1 2 2 6 2 2 3 8 5 7 1 3 9 4 1 */