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
原文地址:https://www.cnblogs.com/shangyu/p/3711165.html