zoukankan      html  css  js  c++  java
  • poj 2112 floyd+Dinic最大流+二分最小值

      题目大意是:

        K台挤奶机器,C头牛,K不超过30,C不超过200,每台挤奶机器最多可以为M台牛工作,给出这些牛和机器之间,牛和牛之间,机器与机器之间的距离,在保证让最多的牛都有机器挤奶的情况下,给出其中距离最长的一头牛移动距离的最小值。

      首先用Floyd求出任意两点之间的最短距离,然后再用二分法限定最多的移动距离d,在求最大流时,搜索增广路的时候同时也判断距离有没有超过d就行了。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 #define _clr(x, y) memset(x, y, sizeof(x))
      5 #define Min(x, y) (x < y ? x : y)
      6 #define INF 0x3f3f3f3f
      7 #define N 1005
      8 using namespace std;
      9 
     10 int flow[N][N], dist[N][N];
     11 int level[N];
     12 int K, C, M,  S, T, ln;
     13 
     14 void Floyd()
     15 {
     16     for(int k=1; k<=ln; k++)
     17         for(int i=1;i<=ln; i++) if(dist[i][k]<INF)
     18             for(int j=1; j<=ln; j++)
     19                 if(dist[i][k]+dist[k][j]<dist[i][j])
     20                     dist[i][j] = dist[i][k]+dist[k][j];
     21 }
     22 
     23 bool bfs()
     24 {
     25     _clr(level, -1);
     26     level[S] = 0;
     27     queue<int> Q;
     28     Q.push(S);
     29     while(!Q.empty())
     30     {
     31         int u = Q.front();
     32         Q.pop();
     33         for(int i=0; i<=T; i++)
     34         {
     35             if(flow[u][i] && level[i]<0)
     36             {
     37                 level[i] = level[u] + 1;
     38                 Q.push(i);
     39             }
     40         }
     41     }
     42     return level[T]> 0 ? 1 : 0;
     43 }
     44 
     45 int dfs(int x, int f)
     46 {
     47     int a;
     48     if(x==T) return f;
     49     for(int i=0; i<=T; i++)
     50     {
     51         if(flow[x][i] && level[i]==level[x]+1 && (a=dfs(i,Min(f,flow[x][i]))))
     52         {
     53             flow[x][i] -= a;
     54             flow[i][x] += a;
     55             return a;
     56         }
     57     }
     58     level[x] = -1;
     59     return 0;
     60 }
     61 
     62 __int64 Dinic(int len)
     63 {       
     64     //    构建残余网络
     65     _clr(flow, 0);
     66     for(int i=1; i<=K; i++)
     67         flow[S][i] = M;
     68     for(int i=K+1; i<=ln; i++)
     69         flow[i][T] = 1;
     70     for(int i=1; i<=K; i++)   // 机器
     71         for(int j=K+1; j<=ln; j++)  // 奶牛
     72             flow[i][j] = (dist[i][j]<=len);
     73 
     74     //      求解最大流
     75     __int64 ans=0, a=0;
     76     while(bfs())
     77         while(a=dfs(0,INF)) ans += a;
     78     return ans;
     79 }
     80 
     81 //  二分求解满足条件的最小解
     82 int Slove()
     83 {
     84     int l=1, r=100000;
     85     while(l<=r)
     86     {
     87         int mid = (l+r)>>1;
     88         if(Dinic(mid)>=C) r = mid-1;
     89         else l = mid+1;
     90     }
     91     return l;
     92 }
     93 int main()
     94 {
     95     while(~scanf("%d%d%d", &K, &C, &M))
     96     {
     97         ln = K+C;
     98         T = ln + 1;
     99         _clr(dist, 0);
    100         for(int i=1; i<=ln; i++)
    101             for(int j=1; j<=ln; j++)
    102             {
    103                 scanf("%d", dist[i]+j);
    104                 if(dist[i][j]==0) dist[i][j]=INF;
    105             }
    106         //// 求出个实体之间的各个最短距离
    107         Floyd();
    108 
    109         printf("%d
    ", Slove());
    110     }
    111     return 0;
    112 }

  • 相关阅读:
    CF1539 VP 记录
    CF1529 VP 记录
    CF875C National Property 题解
    CF1545 比赛记录
    CF 1550 比赛记录
    CF1539E Game with Cards 题解
    CF1202F You Are Given Some Letters... 题解
    vmware Linux虚拟机挂载共享文件夹
    利用SOLR搭建企业搜索平台 之九(solr的查询语法)
    利用SOLR搭建企业搜索平台 之四(MultiCore)
  • 原文地址:https://www.cnblogs.com/khan724/p/4297843.html
Copyright © 2011-2022 走看看