POJ 2112 二分+最大流

题意:

有k个牛奶机跟c头牛。他们之间有路相连,农民想让每个牛能到其中一个牛奶机,又想让走路最远的牛走得最小。

题解:

求最大值最小,不出意外就是二分了

由于要限制总的路径长度,就不能对每条边限制了,于是先floyd求最短路,再二分最长路即可~

不连大于二分值的路径,连小于等于二分值的路径,做最大流就好了~

 

View Code
  1 #include <cstdio>

  2 #include <cstdlib>

  3 #include <cstring>

  4 #include <iostream>

  5 #include <algorithm>

  6 

  7 #define N 250

  8 #define M 600000

  9 #define INF 100000

 10 

 11 using namespace std;

 12 

 13 int map[N][N],m,c,k,l,r,S,T,head[N],next[M],to[M],len[M],q[M<<4],cnt,layer[N],mid,dis[N],num;

 14 

 15 inline void add(int u,int v,int w)

 16 {

 17     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;

 18     to[cnt]=u; len[cnt]=0; next[cnt]=head[v]; head[v]=cnt++;

 19 }

 20 

 21 void read()

 22 {

 23     num=0;

 24     for(int i=1;i<=k+c;i++)

 25         for(int j=1;j<=k+c;j++)

 26         {

 27             scanf("%d",&map[i][j]);

 28             if(map[i][j]==0) map[i][j]=INF;

 29         }

 30     for(int p=1;p<=k+c;p++)//floyd处理最短路 

 31         for(int i=1;i<=k+c;i++)

 32             for(int j=1;j<=k+c;j++)

 33                 if(map[i][p]<INF&&map[p][j]<INF)

 34                     map[i][j]=min(map[i][p]+map[p][j],map[i][j]);

 35 }

 36 

 37 void create() 

 38 {

 39     S=0;T=k+c+1;

 40     memset(head,-1,sizeof head);

 41     cnt=0;

 42     for(int i=1;i<=k;i++) add(S,i,m);

 43     for(int i=k+1;i<=k+c;i++) add(i,T,1);

 44     for(int i=1;i<=k;i++)

 45         for(int j=k+1;j<=k+c;j++)

 46             if(map[i][j]<=mid) add(i,j,1);

 47 }

 48 

 49 bool bfs()

 50 {

 51     memset(layer,-1,sizeof layer);

 52     int h=1,t=2,sta;

 53     layer[S]=0; q[1]=S;

 54     while(h<t)

 55     {

 56         sta=q[h++];

 57         for(int i=head[sta];~i;i=next[i])

 58             if(len[i]>0&&layer[to[i]]<0)

 59             {

 60                 layer[to[i]]=layer[sta]+1;

 61                 q[t++]=to[i];

 62             }

 63     }

 64     return layer[T]!=-1;

 65 }

 66 

 67 int find(int u,int cur_flow)

 68 {

 69     int tmp=0,result=0;

 70     if(u==T) return cur_flow;

 71     for(int i=head[u];~i&&result<cur_flow;i=next[i])

 72         if(len[i]>0&&layer[to[i]]==layer[u]+1)

 73         {

 74             tmp=find(to[i],min(cur_flow-result,len[i]));

 75             len[i]-=tmp; len[i^1]+=tmp; result+=tmp; 

 76         }

 77     if(!result) layer[u]=-1;

 78     return result;

 79 }

 80 

 81 int dinic()

 82 {

 83     create();

 84     int ans=0;

 85     while(bfs()) ans+=find(S,INF);

 86     return ans;

 87 }

 88 

 89 void go()

 90 {

 91     int ans;

 92     l=0,r=100000;

 93     while(l<=r)

 94     {

 95         mid=(l+r)>>1;

 96         if(dinic()>=c) r=mid-1;

 97         else l=mid+1;

 98     }

 99     printf("%d\n",l);

100 }

101 

102 int  main()

103 {

104     scanf("%d%d%d",&k,&c,&m);

105     read();

106     go();

107     return 0;

108 }

 

 

你可能感兴趣的:(poj)