码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1797: [Ahoi2009]Mincut 最小割

时间:2016-07-10 23:14:18      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:

求最小割的可行边与必须边,先求一遍最大流,然后在残量网络上求强连通分量,对于可行边 起始点与结束点要在不同的强连通分量里,对于必须边 起始点要与S在一个SCC里 结束点要与T在一个SCC里。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<queue>
  7 #include<algorithm>
  8 #include<vector>
  9 #define M 1000009
 10 #define EPS 1e-10
 11 #define MO 10000
 12 #define ll long long
 13 using namespace std;
 14 ll read()
 15 {
 16     char ch=getchar();
 17     ll x=0,f=1;
 18     for(;ch<0||ch>9;ch=getchar())
 19         if(ch==-)
 20           f=-1;
 21     for(;ch>=0&&ch<=9;ch=getchar())
 22         x=x*10+ch-0;
 23     return x*f;
 24 }
 25 int dfn[M],low[M],T1,belong[M],sum,t,q[M],n,m,S,T,head[M],next[M],u[M],v[M],cnt=1,d[M],f[M],fr[M];
 26 void jia(int a1,int a2,int a3)
 27 {
 28   cnt++;
 29   fr[cnt]=a1;
 30   next[cnt]=head[a1];
 31   head[a1]=cnt;
 32   u[cnt]=a2;
 33   v[cnt]=a3;
 34 }
 35 bool bfs()
 36 {
 37   memset(d,0,sizeof(int)*(n+1));
 38   d[S]=1;
 39   q[1]=S;
 40   int h=0,t=1;
 41   for(;h<t;)
 42     {
 43       int p=q[++h];
 44       for(int i=head[p];i;i=next[i])
 45         if(v[i]&&!d[u[i]])
 46           {
 47             d[u[i]]=d[p]+1;
 48             if(u[i]==T)
 49               return 1;
 50             q[++t]=u[i];
 51           }
 52     }
 53    return 0;
 54 }
 55 int dinic(int x,int f)
 56 {
 57   if(x==T)
 58     return f;
 59   int rest=f;
 60   for(int i=head[x];i&&rest;i=next[i])
 61     if(v[i]&&d[u[i]]==d[x]+1)
 62       {
 63         int now=dinic(u[i],min(rest,v[i]));
 64         if(!now)
 65           d[u[i]]=0;
 66         rest-=now;
 67         v[i]-=now;
 68         v[i^1]+=now;
 69       }
 70   return f-rest;
 71 }
 72 void tarjin(int x)
 73 {
 74   dfn[x]=low[x]=++T1;
 75   q[++t]=x;
 76   f[x]=1;
 77   for(int i=head[x];i;i=next[i])
 78     if(v[i])
 79       {
 80         if(!dfn[u[i]])
 81           {
 82             tarjin(u[i]);
 83             low[x]=min(low[x],low[u[i]]);
 84           }
 85         else  if(f[u[i]])
 86           low[x]=min(low[x],dfn[u[i]]);
 87       }
 88   if(dfn[x]==low[x])
 89     {
 90       sum++;
 91       for(;q[t]!=x;t--)
 92         {
 93           belong[q[t]]=sum;
 94           f[q[t]]=0; 
 95         }
 96       belong[x]=sum;
 97       f[x]=0;
 98       t--;
 99     }
100 }
101 int main()
102 {
103    n=read();
104    m=read();
105    S=read();
106    T=read();
107    for(int i=1;i<=m;i++)
108      {
109        int a1=read(),a2=read(),a3=read();
110        jia(a1,a2,a3);
111        jia(a2,a1,0);
112      }
113    for(;bfs();)
114      dinic(S,0x7fffffff);
115    for(int i=1;i<=n;i++)
116      if(!dfn[i])
117        tarjin(i);
118    for(int i=2;i<=cnt;i+=2)
119      if(v[i])
120        printf("0 0\n");
121      else
122        {
123          if(belong[fr[i]]==belong[u[i]])
124            printf("0 ");
125          else
126            printf("1 ");
127          if(belong[fr[i]]==belong[S]&&belong[u[i]]==belong[T])
128            printf("1\n");
129          else
130            printf("0\n");
131        }
132    return 0;
133 }
134 

 

bzoj 1797: [Ahoi2009]Mincut 最小割

标签:

原文地址:http://www.cnblogs.com/xiw5/p/5658619.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!