[bzoj1797] [Ahoi2009]Mincut 最小割
问最小割中可能成为割边和一定会成为割边的边有哪些。
膜了半天各路题解。
比较详细的解释:
http://blog.csdn.net/horizon_smz/article/details/50889806
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=4023,maxm=60233; 7 struct zs{ 8 int too,pre,flow; 9 }e[maxm<<1];int tot,last[maxn]; 10 short dis[maxn],dl[maxn]; 11 int st[maxn],top,dfn[maxn],low[maxn],tim,bel[maxn],cnt; 12 bool ins[maxn]; 13 int i,j,k,n,m,s,t; 14 15 int ra;char rx; 16 inline int read(){ 17 rx=getchar(),ra=0; 18 while(rx<'0'||rx>'9')rx=getchar(); 19 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 20 } 21 inline bool bfs(){ 22 memset(dis,0,(n+1)<<1); 23 int l=0,r=1,i,now;dl[1]=s,dis[s]=1; 24 while(l<r&&!dis[t]) 25 for(i=last[now=dl[++l]];i;i=e[i].pre)if(e[i].flow&&!dis[e[i].too]) 26 dl[++r]=e[i].too,dis[e[i].too]=dis[now]+1; 27 return dis[t]; 28 } 29 inline int min(int a,int b){return a<b?a:b;} 30 int dfs(int x,int mx){ 31 if(x==t)return mx; 32 int i,used=0,w; 33 for(i=last[x];i;i=e[i].pre)if(e[i].flow&&dis[e[i].too]==dis[x]+1){ 34 w=dfs(e[i].too,min(e[i].flow,mx-used));if(w){ 35 e[i].flow-=w,e[i^1].flow+=w,used+=w; 36 if(used==mx)return mx; 37 } 38 } 39 dis[x]=0;return used; 40 } 41 42 void tarjan(int x){ 43 int i; 44 dfn[x]=low[x]=++tim,ins[x]=1,st[++top]=x; 45 for(i=last[x];i;i=e[i].pre)if(e[i].flow){ 46 if(!dfn[e[i].too])tarjan(e[i].too),low[x]=min(low[x],low[e[i].too]); 47 else if(ins[e[i].too])low[x]=min(low[x],dfn[e[i].too]); 48 } 49 if(low[x]==dfn[x]){ 50 cnt++; 51 while(st[top]!=x)bel[st[top]]=cnt,ins[st[top]]=0,top--; 52 bel[x]=cnt,ins[x]=0,top--; 53 } 54 } 55 56 inline void insert(int a,int b,int c){ 57 e[++tot].too=b,e[tot].flow=c,e[tot].pre=last[a],last[a]=tot, 58 e[++tot].too=a,e[tot].flow=0,e[tot].pre=last[b],last[b]=tot; 59 } 60 61 int main(){ 62 n=read(),m=read(),s=read(),t=read(),tot=1; 63 for(i=1;i<=m;i++)j=read(),k=read(),insert(j,k,read()); 64 while(bfs())dfs(s,1002333333); 65 for(i=1;i<=n;i++)if(!dfn[i])tarjan(i); 66 for(i=2;i<=tot;i+=2){ 67 if(e[i].flow){puts("0 0");continue;} 68 if(bel[e[i^1].too]!=bel[e[i].too])printf("1 ");else printf("0 "); 69 if(bel[e[i^1].too]==bel[s]&&bel[e[i].too]==bel[t])puts("1");else puts("0"); 70 } 71 return 0; 72 } 73