POJ 2455 二分+最大流

题意:

从起点到终点有T条不相交路径的最大边的最小值。

题解:

典型的二分答案!最大流还真爱和二分一起出啊~

View Code
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cstdio>
  5 #include <algorithm>
  6 
  7 #define N 1000
  8 #define M 1000000
  9 #define INF 1e9
 10 
 11 using namespace std;
 12 
 13 int head[N],next[M],to[M],len[M];
 14 int layer[N],q[M*10];
 15 int n,m,cnt,tot,S,T,l,r,mid,sm;
 16 
 17 struct PX
 18 {
 19     int a,c,b;
 20 }px[M];
 21 
 22 inline bool cmp(const PX &a,const PX &b)
 23 {
 24     return a.c<b.c;
 25 }
 26 
 27 inline void add(int u,int v,int w)
 28 {
 29     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;
 30     to[cnt]=u; len[cnt]=0; next[cnt]=head[v]; head[v]=cnt++;
 31 }
 32 
 33 inline void read()
 34 {
 35     l=0;r=0; S=1; T=n; tot=0;
 36     for(int i=1;i<=m;i++)
 37     {
 38         tot++;
 39         scanf("%d%d%d",&px[tot].a,&px[tot].b,&px[tot].c);
 40         ++tot; px[tot].a=px[tot-1].b; px[tot].b=px[tot-1].a; px[tot].c=px[tot-1].c;
 41         r=max(r,px[tot].c);
 42     }
 43     sort(px+1,px+1+tot,cmp);
 44 }
 45 
 46 inline void build()
 47 {
 48     memset(head,-1,sizeof head); cnt=0;
 49     for(int i=1;i<=tot;i++)
 50     {
 51         if(px[i].c>mid) break;
 52         add(px[i].a,px[i].b,1);
 53     }
 54 }
 55 
 56 inline bool bfs()
 57 {
 58     memset(layer,-1,sizeof layer);
 59     int h=1,t=2,sta;
 60     q[1]=S; layer[S]=0;
 61     while(h<t)
 62     {
 63         sta=q[h++];
 64         for(int i=head[sta];~i;i=next[i])
 65             if(len[i]&&layer[to[i]]<0)
 66             {
 67                 layer[to[i]]=layer[sta]+1;
 68                 q[t++]=to[i];
 69             }
 70     }
 71     return layer[T]!=-1;
 72 }
 73 
 74 inline int find(int u,int cur_flow)
 75 {
 76     if(u==T) return cur_flow;
 77     int res=0,tmp;
 78     for(int i=head[u];~i&&res<cur_flow;i=next[i])
 79         if(len[i]&&layer[to[i]]==layer[u]+1)
 80         {
 81             tmp=find(to[i],min(cur_flow-res,len[i]));
 82             len[i]-=tmp; len[i^1]+=tmp; res+=tmp;
 83         }
 84     if(!res) layer[u]=-1;
 85     return res;
 86 }
 87 
 88 inline int dinic()
 89 {
 90     int ans=0;
 91     while(bfs()) ans+=find(S,INF);
 92     return ans;
 93 }
 94 
 95 inline void go()
 96 {
 97     int ans;
 98     while(l<=r)
 99     {
100         mid=(l+r)>>1;
101         build();
102         if(dinic()>=sm) ans=mid,r=mid-1;
103         else l=mid+1;
104     }
105     printf("%d\n",ans);
106 }
107 
108 int main()
109 {
110     while(scanf("%d%d%d",&n,&m,&sm)!=EOF) read(),go();
111     return 0;
112 }
没有人能阻止我前进的步伐,除了我自己!
原文地址:https://www.cnblogs.com/proverbs/p/2850368.html