zoukankan      html  css  js  c++  java
  • POJ 2112 挤牛奶 floyd+最大流+二分

    题意:

    有k个挤奶器,c头牛..每个挤奶器和每头牛之间都有特定的距离..k个挤奶器的位置用1~k的编号表示..奶牛的位置用k+1~k+c表示

    每个挤奶器每天最多为m头牛挤奶..

    求安排每头牛到挤奶器前的最大距离的最小值..

    思路:

    先用floyd求出每头牛到每台挤奶器的最短距离..

    然后用二分判断最大距离最小值是多少..

    check()函数就是根据按距离建图后这个网络流的最大流==牛的头数

    其中建图先建一个超级源点..作为每头牛的前驱..他们的流量为1..

    然后建一个超级汇点..作为每台挤奶器的后继..他们的流量为m..

    如果由floyd求出的最短距离 >= 二分假设的最大距离最小值x..就连线..然后根据这个求出的图来求最大流..

    Tips:

    ※ 要注意全局变量和局部变量不要冲撞..

    ※ 求最大流算法很多..EK/Dicnic..还有..%&@^%$%

    ※ 这道题还可以用二分图的多重匹配来完成..<没做>

    Code:

    <EK>
     1 #include <stdio.h>
     2 #include <cstring>
     3 #include <queue>
     4 using namespace std;
     5 #define INF 0x1f1f1f1f
     6 #define clr(x) memset(x, 0, sizeof(x))
     7 
     8 int G[250][250], K, c, m, n;
     9 int arr[250][250];
    10 int dis[250][250];
    11 int flow[250][250], a[250], f, p[250];
    12 
    13 
    14 void init(int x)
    15 {
    16     int i, j, k;
    17     clr(G);
    18     for(i = 1; i <= K; ++i)
    19     G[i][n+1] = m;
    20     for(i = K+1; i <= n; ++i)
    21     G[0][i] = 1;
    22 
    23     for(i = K+1; i <= n; ++i)
    24     for(j = 1; j <= K; ++j){
    25         if(arr[i][j] && arr[i][j] <= x) G[i][j] = 1;
    26     }
    27 }
    28 
    29 int EK(int s, int t)
    30 {
    31     clr(flow);
    32     clr(p);
    33     queue<int> q;
    34     int f = 0;
    35     while(1)
    36     {
    37         clr(a);
    38         a[s] = INF;
    39         q.push(s);
    40         while(!q.empty())
    41         {
    42             int u = q.front();
    43             q.pop();
    44             for(int v = 0; v <= n+1; ++v)
    45             if(!a[v] && G[u][v] > flow[u][v])
    46             {
    47                 p[v] = u;
    48                 q.push(v);
    49                 a[v] = a[u] < G[u][v] - flow[u][v]?a[u]:G[u][v]-flow[u][v];
    50             }
    51         }
    52         if(a[t] == 0) break;
    53         for(int u = t; u != s; u = p[u]){
    54             flow[p[u]][u] += a[t];
    55             flow[u][p[u]] -= a[t];
    56         }
    57         f += a[t];
    58 
    59     }
    60     return f;
    61 }
    62 
    63 int main()
    64 {
    65     int i, j, k;
    66     while(scanf("%d %d %d", &K, &c, &m) != EOF)
    67     {
    68         clr(arr);
    69         n = K+c;
    70         for(i = 1; i <= n; ++i)
    71         for(j = 1; j <= n; ++j)
    72         scanf("%d", &arr[i][j]);
    73 
    74         for(k = 1; k <= n; ++k)
    75         for(i = 1; i <= n; ++i){
    76             if(arr[i][k])
    77             for(j = 1; j <= n; ++j){
    78                 if(arr[k][j] && (arr[i][k] + arr[k][j] < arr[i][j] || arr[i][j] == 0))
    79                 arr[i][j] = arr[i][k]+arr[k][j];
    80             }
    81         }
    82         int low, top, mid;
    83         low = top = 0;
    84         for(i = K+1; i <= n; ++i)
    85         for(j = 1; j <= K; ++j)
    86         if(arr[i][j] > top) top = arr[i][j];
    87 
    88         int tmp;
    89         while(low < top)
    90         {
    91             mid = (low+top)/2;
    92             init(mid);
    93             tmp = EK(0, n+1);
    94             if(tmp != c) low = mid+1;
    95             else top = mid;
    96         }
    97         printf("%d\n", low);
    98     }
    99 }

     

    <Dicnic>
     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <cstring>
     4 using namespace std;
     5 #define INF 100000
     6 #define MAX 300
     7 
     8 int G[MAX][MAX];
     9 int map[MAX][MAX];
    10 bool sign[MAX][MAX];
    11 bool used[MAX];
    12 int K, c, n, m;
    13 
    14 void bg(int x)
    15 {
    16     int i, j;
    17     memset(map, 0, sizeof(map));
    18 
    19     for(i = K+1; i <= n; ++i)
    20     map[0][i] = 1;
    21     for(i = 1; i <= K; ++i)
    22     map[i][n+1] = m;
    23 
    24     for(i = K+1; i <= n; ++i)
    25     for(j = 1; j <= K; ++j)
    26     if(G[i][j] <= x) map[i][j] = 1;
    27 }
    28 
    29 bool bfs()
    30 {
    31     memset(used, 0, sizeof(used));
    32     memset(sign, 0, sizeof(sign));
    33     int queue[100*MAX] = {0};
    34     queue[0] = 0;
    35     used[0] = 1;
    36     int t = 1, f = 0;
    37     while(f < t)
    38     {
    39         for(int i = 0; i <= n+1; ++i)
    40         if(!used[i] && map[queue[f]][i]){
    41             queue[t++] = i;
    42             used[i] = 1;
    43             sign[queue[f]][i] = 1;
    44         }
    45         f++;
    46     }
    47     if(used[n+1]) return true;
    48     else return false;
    49 }
    50 
    51 int dfs(int v, int sum)
    52 {
    53     int i, s, t;
    54     if( v == n+1) return sum;
    55     s = sum;
    56     for(i = 0; i <= n+1; ++i){
    57         if(sign[v][i]){
    58             t = dfs(i, min(map[v][i], sum));
    59             map[v][i] -= t;
    60             map[i][v] += t;
    61             sum -= t;
    62         }
    63     }
    64     return s-sum;
    65 }
    66 
    67 int main()
    68 {
    69     int i, j, k, l, r, mid, ans;
    70     scanf("%d %d %d", &K, &c, &m);
    71     n = K+c;
    72     for(i = 1; i <= n; ++i)
    73     for(j = 1; j <= n; ++j){
    74         scanf("%d", &G[i][j]);
    75         if(G[i][j] == 0) G[i][j] = INF;
    76     }
    77 
    78     for(k = 1; k <= n; ++k)
    79     for(i = 1; i <= n; ++i){
    80         if(G[i][k] != INF)
    81         for(j = 1; j <= n; ++j)
    82         G[i][j] = min(G[i][j], G[i][k]+G[k][j]);
    83     }
    84 
    85     l = 0, r = 10000;
    86     while(l < r)
    87     {
    88         mid = (l+r)/2;
    89         ans = 0;
    90         bg(mid);
    91         while(bfs()) ans += dfs(0, INF);
    92         if(ans >= c) r = mid;
    93         else l = mid+1;
    94     }
    95     printf("%d\n", r);
    96     return 0;
    97 }

     

  • 相关阅读:
    HDU 4334
    HDU 1280
    HDU 1060
    HDU 4033
    大三角形分成4个面积相等的小三角形
    HDU 1087
    HDU 4313
    Sleep(0)及其使用场景
    Decorator(装饰、油漆工)对象结构型模式
    Debug Assertion Failed!
  • 原文地址:https://www.cnblogs.com/Griselda/p/2625412.html
Copyright © 2011-2022 走看看