bzoj 4519: [Cqoi2016]不同的最小割 最小割树

怎么求一张无向图中任意两点之间的最小割?

http://fanhq666.blog.163.com/blog/static/8194342620113495335724/

一张无向图不同的最小割最多有n-1个。

所以可以用这些最小割建出一棵最小割树。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<queue>
  6 #define inf 0x3f3f3f3f
  7 #define N 855
  8 #define M 400005
  9 using namespace std;
 10 int read()
 11 {
 12     int p=0;char c=getchar();
 13     while(c<'0'||c>'9')c=getchar();
 14     while(c>='0'&&c<='9')p=p*10+c-'0',c=getchar();
 15     return p;
 16 }
 17 int head[N],ver[M],nxt[M],f[M],tot,ch[N];
 18 void add(int a,int b,int c)
 19 {
 20     tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;f[tot]=c;return ;
 21 }
 22 queue<int>q;int S,T;
 23 bool tell()
 24 {
 25     memset(ch,-1,sizeof(ch));
 26     q.push(S);ch[S]=0;
 27     while(!q.empty())
 28     {
 29         int tmp=q.front();q.pop();
 30         for(int i=head[tmp];i;i=nxt[i])
 31         {
 32             if(f[i]&&ch[ver[i]]==-1)
 33             {
 34                 ch[ver[i]]=ch[tmp]+1;
 35                 q.push(ver[i]);
 36             }
 37         }
 38     }
 39     return ch[T]!=-1;
 40 }
 41 int zeng(int a,int b)
 42 {
 43     if(a==T)return b;
 44     int r=0;
 45     for(int i=head[a];i&&b>r;i=nxt[i])
 46     {
 47         if(f[i]&&ch[ver[i]]==ch[a]+1)
 48         {
 49             int t=zeng(ver[i],min(f[i],b-r));
 50             f[i]-=t;f[i^1]+=t;r+=t;
 51         }
 52     }
 53     if(!r)ch[a]=-1;
 54     return r;
 55 }
 56 int dinic()
 57 {
 58     int r=0,t;
 59     while(tell())while(t=zeng(S,inf))r+=t;
 60     return r;
 61 }
 62 void hui()
 63 {
 64     for(int i=2;i<=tot;i+=2)
 65     {
 66         f[i]=f[i^1]=(f[i]+f[i^1])>>1;
 67     }return ;
 68 }
 69 int tim;
 70 int c[N];
 71 void dfs(int x)
 72 {
 73     c[x]=tim;
 74     for(int i=head[x];i;i=nxt[i])
 75     {
 76         if(f[i]&&c[ver[i]]!=tim)dfs(ver[i]);
 77     }
 78     return ;
 79 }
 80 int p[N];
 81 int ans[N],cnt;
 82 int n,m;
 83 int st[N],st2[N];
 84 void solve(int l,int r)
 85 {
 86     if(l==r)return ;
 87     hui();
 88     S=p[l];T=p[r];
 89     int tmp=dinic();
 90     tim++;dfs(S);
 91     ans[++cnt]=tmp;
 92     int top1=0,top2=0;
 93     for(int i=l;i<=r;i++)
 94     {
 95         if(c[p[i]]==tim)st[++top1]=p[i];
 96         else st2[++top2]=p[i];
 97     }
 98     for(int i=l;i<=l+top1-1;i++)p[i]=st[i-l+1];
 99     for(int i=l+top1;i<=r;i++)p[i]=st2[i-l-top1+1];
100     solve(l,l+top1-1);solve(l+top1,r);
101 }
102 int main()
103 {
104     scanf("%d%d",&n,&m);
105     int t1,t2,t3;tot=1;
106     for(int i=1;i<=m;i++)
107     {
108         t1=read();t2=read();t3=read();
109         add(t1,t2,t3);add(t2,t1,t3);
110     }
111     for(int i=1;i<=n;i++)p[i]=i;
112     solve(1,n);
113     sort(ans+1,ans+cnt+1);
114     int as=0;
115     for(int i=1;i<=cnt;i++)
116     {
117         if(i==1||ans[i]!=ans[i-1])
118         {
119             as++;
120         }
121     }
122     printf("%d\n",as);
123 }

 

                    

posted @ 2017-03-28 17:14  SD_le  阅读(292)  评论(0编辑  收藏  举报
重置按钮