BZOJ-2561: 最小生成树(最小割)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2561
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define maxn 20010 #define maxm 400100 int e[maxn],u[maxm],ne[maxm],v[maxm],l[maxm],n,m,tt=1; int s,t,L; bool been[maxn]; void add(int x,int y,int z){ ne[++tt]=e[x],e[x]=tt,v[tt]=y,l[tt]=z; } int ch[maxn]; bool bfs(){ memset(ch,-1,sizeof(ch)); queue<int> jj; jj.push(s); ch[s]=0; while(!jj.empty()){ int x=jj.front(); jj.pop(); for(int i=e[x];i;i=ne[i])if(u[i]&&ch[v[i]]==-1){ ch[v[i]]=ch[x]+1; jj.push(v[i]); } } return ch[t]!=-1; } int zeng(int no,int mm){ if(no==t)return mm; int r=mm; for(int i=e[no];i&&r;i=ne[i])if(u[i]&&ch[v[i]]==ch[no]+1){ int k=zeng(v[i],min(u[i],r)); r-=k,u[i]-=k,u[i^1]+=k; } if(r==mm)return ch[no]=-1,0; return mm-r; } int dinic(){ int tt,r=0; while(bfs())while(tt=zeng(s,0x3fffffff))r+=tt; return r; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); } scanf("%d%d%d",&s,&t,&L); for(int i=1;i<=tt;i++)if(l[i]<L)u[i]=1; else u[i]=0; int ans=dinic(); for(int i=1;i<=tt;i++)if(l[i]>L)u[i]=1; else u[i]=0; ans+=dinic(); cout<<ans; }
两遍最小割