poj 2112 Optimal Milking 最大流

http://poj.org/problem?id=2112

【题意】  k个机器,每个机器最多服务m头牛。c头牛,每个牛需要1台机器来服务。给出一个矩阵表示每两个实体之间的直接距离。(注意两个实体没有直接

             距离的时候用0表示) 问:让所有的牛都被服务的情况下,使走的最远的牛的距离最短,求这个距离。

【思路】  先用floyd求出每两个实体间的最短距离,再二分所求的距离len。

【建图】 源点向每个机器连边,容量为m。每个机器向距离小于len的牛连边,容量为1。每头牛向汇点连边,容量为1。若最大流为牛的数量,说明每头牛都

              服务到了,这个len可行。

 

  1 #include<iostream>
  2 #include<vector>
  3 #include<cstring>
  4 #include<queue>
  5 #include<cstdio>
  6 using namespace std;
  7 #define maxx 250
  8 #define INF 9999999
  9 
 10 int c[maxx][maxx],f[maxx][maxx],p[maxx], a[maxx];
 11 int d[maxx][maxx];
 12 int machine,cow,maxc;
 13 
 14 void add(int u,int v,int w)
 15 {
 16     c[u][v]=w;
 17 }
 18 
 19 int maxflow(int s,int t,int n)
 20 {
 21     queue<int> q;
 22     memset(f,0,sizeof(f));
 23     int flow=0;
 24     while(1)
 25     {
 26         memset(a,0,sizeof(a));
 27         a[s] = INF;
 28         q.push(s);
 29 
 30         while(!q.empty())
 31         {
 32             int u = q.front();
 33             q.pop();
 34             for(int v = 1; v <= n; v++) if(!a[v] && c[u][v] > f[u][v])
 35                 {
 36                     p[v] = u;
 37                     q.push(v);
 38                     a[v] = min(a[u], c[u][v]-f[u][v]);
 39                 }
 40         }
 41 
 42         if(a[t] == 0)
 43             break;
 44         for(int u = t; u != s; u = p[u])
 45         {
 46             f[p[u]][u] += a[t];
 47             f[u][p[u]] -= a[t];
 48         }
 49         flow += a[t];
 50     }
 51     return flow;
 52 }
 53 
 54 bool ok(int x)
 55 {
 56     memset(c,0,sizeof(c));
 57     memset(f,0,sizeof(f));  //!!  注意要清零啊!!泪奔~
 58     int n=machine+cow;
 59     for(int i=1; i<=machine; i++)
 60     {
 61         add(0,i,maxc);
 62         for(int j=machine+1; j<=machine+cow; j++)
 63             if(d[i][j]<=x)
 64                 add(i,j,1);
 65     }
 66     for(int i=machine+1; i<=n; i++)
 67         add(i,n+1,1);
 68     int flow;
 69     flow=maxflow(0,n+1,n+1);
 70     // printf("flow %d     x %d\n",flow,x);
 71     if(flow==cow)
 72         return true;
 73     return false;
 74 }
 75 
 76 int solve(int max1)
 77 {
 78     int left=0,right=max1,minn=right;
 79     while(left<=right)              //之前习惯性写成了 left<right了。。
 80     {
 81         int mid;
 82         mid=(left+right)/2;
 83         if(ok(mid))
 84         {
 85             minn=min(minn,mid);
 86             right=mid-1;
 87         }
 88         else left=mid+1;
 89     }
 90     return minn;
 91 }
 92 
 93 int main()
 94 {
 95     int k,c,m;
 96     while(~scanf("%d%d%d",&machine,&cow,&maxc))
 97     {
 98         int n=machine+cow;
 99         for(int i=1; i<=n; i++)
100             for(int j=1; j<=n; j++)
101             {
102                 scanf("%d",&d[i][j]);
103                 if(d[i][j]==0&&i!=j)
104                     d[i][j]=INF;
105             }
106 
107         for(int m=1; m<=n; m++)
108             for(int i=1; i<=n; i++)
109                 for(int j=1; j<=n; j++)
110                     d[i][j]=min(d[i][j],d[i][m]+d[m][j]);
111                     
112         int max1=0;
113         for(int i=1; i<=n; i++)
114             for(int j=1; j<=n; j++)
115                 max1=max(max1,d[i][j]);
116                 
117         printf("%d\n",solve(max1));
118     }
119     return 0;
120 }

 

posted @ 2014-08-31 17:37  galaxy77  阅读(179)  评论(0编辑  收藏  举报