poj2112Optimal Milking(二分+最大流)

链接

floyd求出牛到机器的最短距离,二分距离,小于当前距离的边容量设为1,求出满容量下的最短距离。

EK算法 

  1 #include <iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<stdlib.h>

  6 #include<vector>

  7 #include<cmath>

  8 #include<queue>

  9 #include<set>

 10 using namespace std;

 11 #define N 255

 12 #define LL long long

 13 #define INF 0xfffffff

 14 const double eps = 1e-8;

 15 const double pi = acos(-1.0);

 16 const double inf = ~0u>>2;

 17 int path[N],flow[N],gh[N][N],st,en;

 18 int w[N][N];

 19 int bfs()

 20 {

 21     int i;

 22     memset(path,-1,sizeof(path));

 23     for(i = 1 ; i <= en ; i++)

 24     flow[i] = INF;

 25     queue<int>q;

 26     q.push(1);

 27     while(!q.empty())

 28     {

 29         int tk = q.front();

 30         q.pop();

 31         if(tk==en)

 32         break;

 33         for(i = 1 ; i <= en ; i++)

 34         {

 35             if(path[i]==-1&&gh[tk][i])

 36             {

 37                 path[i] = tk;

 38                 flow[i] = min(flow[tk],gh[tk][i]);

 39                 q.push(i);

 40             }

 41         }

 42     }

 43     if(path[en]==-1)

 44     return -1;

 45     return flow[en];

 46 }

 47 int EK()

 48 {

 49     int now,pre,sum=0,k;

 50     while((k=bfs())!=-1)

 51     {

 52         sum+=k;

 53         now = en;

 54         while(now!=st)

 55         {

 56             pre = path[now];

 57             gh[pre][now]-=k;

 58             gh[now][pre]+=k;

 59             now = pre;

 60         }

 61     }

 62     return sum;

 63 }

 64 int main()

 65 {

 66     int k,c,i,g,j,m;

 67     while(scanf("%d%d%d",&k,&c,&m)!=EOF)

 68     {

 69         int n = k+c;

 70         for(i = 2; i <= n+1; i++)

 71             for(j = 2;j <= n+1 ; j++)

 72                 w[i][j] = INF;

 73         for(i = 2;i <= n+1 ; i++)

 74             for(j = 2; j <= n+1 ; j++)

 75             {

 76                 scanf("%d",&w[i][j]);

 77                 if(w[i][j]==0) w[i][j] = INF;

 78                 if(i==j) w[i][i] = 0;

 79                 w[j][i] = w[i][j];

 80             }

 81         for(i = 2 ; i <= n+1; i++)

 82             for(j = 2; j <= n+1 ;j++)

 83                 for(g = 2;g <= n+1; g++)

 84                 w[j][g] = min(w[j][g],w[j][i]+w[i][g]);

 85         st = 1;

 86         en = n+2;

 87         int low = 0,high = 10000,mid;

 88         while(low<=high)

 89         {

 90             mid = (low+high)>>1;

 91             memset(gh,0,sizeof(gh));

 92             for(i = 2; i <= k+1 ; i++)

 93             gh[i][en] = m;

 94             for(i = k+2;  i <= n+1; i++)

 95             gh[st][i] = 1;

 96             for(i = k+2; i <= n+1; i++)

 97                 for(j = 2; j <= k+1 ; j++)

 98                 if(w[i][j]<=mid)

 99                 gh[i][j] = w[i][j];

100             //cout<<EK()<<endl;

101             if(EK()==c)

102             high = mid-1;

103             else

104             low =mid+1;

105         }

106         cout<<low<<endl;

107     }

108     return 0;

109 }
View Code

 

你可能感兴趣的:(poj)