zoukankan      html  css  js  c++  java
  • Optimal Milking POJ-2112(最大流)

    题意:

    有C头奶牛和K台挤奶机,已知每台挤奶机只能给M头牛挤奶。奶牛编号从K+1 到 K+C,挤奶机编号从1 到 K。现在给你一个 (K + C) * (K + C)的矩阵,矩阵第 i 行 第 j 列 的元素代表第i个点到第j个点的距离。求给每头奶牛挤奶的,使得C头奶牛需要行走的路程中的最大路程的最小值。

    思路:

    Floyd求每头奶牛到挤奶机的最小距离,二分答案,每次 check 对于距离小于 mid 的 i ,j 建边,判断最大流是否等于奶牛数。

    代码:

      1 //#include<bits/stdc++.h>
      2 #include <set>
      3 #include <map>
      4 #include <stack>
      5 #include <cmath>
      6 #include <queue>
      7 #include <cstdio>
      8 #include <string>
      9 #include <vector>
     10 #include <cstring>
     11 #include <iostream>
     12 #include <algorithm>
     13 
     14 #define ll long long
     15 #define pll pair<ll,ll>
     16 #define pii pair<int,int>
     17 #define bug printf("*********
    ")
     18 #define FIN freopen("input.txt","r",stdin);
     19 #define FON freopen("output.txt","w+",stdout);
     20 #define IO ios::sync_with_stdio(false),cin.tie(0)
     21 #define ls root<<1
     22 #define rs root<<1|1
     23 #define Q(a) cout<<a<<endl
     24 
     25 using namespace std;
     26 const int inf = 0x3f3f3f3f;
     27 const ll Inf = 1e18 + 7;
     28 const int maxn = 1e5 + 5;
     29 const int mod = 1e9 + 7;
     30 
     31 ll gcd(ll a, ll b)
     32 {
     33     return b ? gcd(b, a % b) : a;
     34 }
     35 
     36 ll lcm(ll a, ll b)
     37 {
     38     return a / gcd(a, b) * b;
     39 }
     40 
     41 ll read()
     42 {
     43     ll p = 0, sum = 0;
     44     char ch;
     45     ch = getchar();
     46     while (1)
     47     {
     48         if (ch == '-' || (ch >= '0' && ch <= '9'))
     49             break;
     50         ch = getchar();
     51     }
     52 
     53     if (ch == '-')
     54     {
     55         p = 1;
     56         ch = getchar();
     57     }
     58     while (ch >= '0' && ch <= '9')
     59     {
     60         sum = sum * 10 + ch - '0';
     61         ch = getchar();
     62     }
     63     return p ? -sum : sum;
     64 }
     65 
     66 struct Dinic
     67 {
     68     int head[maxn], tot, cur[maxn];
     69     int dis[maxn];
     70     int s, e;
     71     queue<int>q;
     72 
     73     struct node
     74     {
     75         int v, w;
     76         int next;
     77     }p[maxn];
     78 
     79     void init()
     80     {
     81         tot = 0;
     82         memset(head, -1, sizeof head);
     83     }
     84 
     85     void add(int u, int v, int w)
     86     {
     87         p[tot].v = v;
     88         p[tot].w = w;
     89         p[tot].next = head[u];
     90         head[u] = tot++;
     91     }
     92 
     93     void addEdge(int u, int v, int w)
     94     {
     95         add(u, v, w);
     96         add(v, u, 0);
     97     }
     98 
     99     bool bfs()
    100     {
    101         memset(dis, 0, sizeof dis);
    102         while (!q.empty())   q.pop();
    103         dis[s] = 1;
    104         q.push(s);
    105         while (!q.empty())
    106         {
    107             int x = q.front();
    108             q.pop();
    109             for (int i = head[x]; i != -1; i = p[i].next)
    110             {
    111                 int v = p[i].v, w = p[i].w;
    112                 if (!dis[v] && w)
    113                 {
    114                     dis[v] = dis[x] + 1;
    115                     q.push(v);
    116                 }
    117             }
    118         }
    119         if (dis[e])  return true;
    120         return false;
    121     }
    122 
    123     int dfs(int x, int W)
    124     {
    125         if (x == e || W == 0)  return W;
    126         int res = 0;
    127         for (int i = cur[x]; i != -1; i = p[i].next)
    128         {
    129             cur[x] = p[i].next;
    130             int v = p[i].v, w = p[i].w;
    131             if (dis[v] == dis[x] + 1)
    132             {
    133                 int f = dfs(v, min(w, W));
    134                 p[i].w -= f;
    135                 p[i ^ 1].w += f;
    136                 W -= f;
    137                 res += f;
    138                 if (W == 0)    break;
    139             }
    140         }
    141         return res;
    142     }
    143 
    144     int getMaxFlow()
    145     {
    146         int ans = 0;
    147         while (bfs())
    148         {
    149             for (int i = s; i <= e; ++i) cur[i] = head[i];
    150             ans += dfs(s, inf);
    151         }
    152         return ans;
    153     }
    154 }DC;
    155 
    156 struct stortest_Floyd {
    157     int a[5000][5000];
    158     void floyd(int num) {
    159         for (int k = 1; k <= num; k++) {
    160             for (int i = 1; i <= num; i++) {
    161                 for (int j = 1; j <= num; j++) {
    162                     if (a[i][j] > a[i][k] + a[k][j]) {
    163                         a[i][j] = a[i][k] + a[k][j];
    164                     }
    165                 }
    166             }
    167         }
    168     }
    169 }Floyd;
    170 
    171 int k, c, m;
    172 int num;
    173 
    174 void add(int x)
    175 {
    176     for (int i = 1; i <= k; ++i)
    177     {
    178         for (int j = k + 1; j <= num; ++j)
    179         {
    180             if (Floyd.a[i][j] <= x)
    181                 DC.addEdge(j, i, 1);
    182         }
    183     }
    184     for (int i = 1; i <= k; ++i)
    185     {
    186         DC.addEdge(i, DC.e, m);
    187     }
    188     for (int i = k + 1; i <= num; ++i)
    189     {
    190         DC.addEdge(DC.s, i, 1);
    191     }
    192 }
    193 
    194 int main()
    195 {
    196     while (~scanf("%d %d %d", &k, &c, &m))
    197     {
    198         num = k + c;
    199         DC.s = 0, DC.e = num + 1;
    200         int nv = num + 2;
    201 
    202         for (int i = 1; i <= num; ++i)
    203         {
    204             for (int j = 1; j <= num; ++j)
    205             {
    206                 scanf("%d", &Floyd.a[i][j]);
    207                 if (i != j && !Floyd.a[i][j])
    208                 {
    209                     Floyd.a[i][j] = inf;
    210                 }
    211             }
    212         }
    213         Floyd.floyd(num);
    214 
    215         int l = 0, r = inf;
    216         int ans = 0;
    217         while (l <= r)
    218         {
    219             int mid = (l + r) / 2;
    220             DC.init();
    221             add(mid);
    222             int res = DC.getMaxFlow();
    223             if (res == c)
    224             {
    225                 ans = mid;
    226                 r = mid - 1;
    227             }
    228             else l = mid + 1;
    229         }
    230         printf("%d
    ", ans);
    231     }
    232 }
  • 相关阅读:
    java-ApiDemo
    java编译器特性
    java
    java
    java
    java
    java
    java
    hdoj 3549 Flow Problem(最大网络流)
    hdoj 1269 迷宫城堡(强连通分量)
  • 原文地址:https://www.cnblogs.com/zhang-Kelly/p/12593195.html
Copyright © 2011-2022 走看看