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 }

 

 

你可能感兴趣的:(poj)