POJ_2112_Optimal Milking 这里有超级快的网络流板子

Posted qldabiaoge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ_2112_Optimal Milking 这里有超级快的网络流板子相关的知识,希望对你有一定的参考价值。

Description

FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 <= C <= 200) cows. A set of paths of various lengths runs among the cows and the milking machines. The milking machine locations are named by ID numbers 1..K; the cow locations are named by ID numbers K+1..K+C.

Each milking point can "process" at most M (1 <= M <= 15) cows each day.

Write a program to find an assignment for each cow to some milking machine so that the distance the furthest-walking cow travels is minimized (and, of course, the milking machines are not overutilized). At least one legal assignment is possible for all input data sets. Cows can traverse several paths on the way to their milking machine.

Input

* Line 1: A single line with three space-separated integers: K, C, and M.

* Lines 2.. ...: Each of these K+C lines of K+C space-separated integers describes the distances between pairs of various entities. The input forms a symmetric matrix. Line 2 tells the distances from milking machine 1 to each of the other entities; line 3 tells the distances from machine 2 to each of the other entities, and so on. Distances of entities directly connected by a path are positive integers no larger than 200. Entities not directly connected by a path have a distance of 0. The distance from an entity to itself (i.e., all numbers on the diagonal) is also given as 0. To keep the input lines of reasonable length, when K+C > 15, a row is broken into successive lines of 15 numbers and a potentially shorter line to finish up a row. Each new row begins on its own line.

Output

A single line with a single integer that is the minimum possible total distance for the furthest walking cow.

Sample Input

2 3 2
0 3 2 1 1
3 0 3 2 0
2 3 0 1 0
1 2 1 0 2
1 0 0 2 0

Sample Output

2

 

这个板子有着很多玄学优化  反正特别特别快

 

题意:k个机器,每个机器最多服务m头牛。

c头牛,每个牛需要1台机器来服务

。告诉你牛与机器每个之间的直接距离。

问:让所有的牛都被服务的情况下,

使走的最远的牛的距离最短,求这个距离。

因为这题求得是最大值得最小值 这个是常见的二分套路

这题行用floyd 跑一个最短路

然后二分枚举长度连边

 

 

 

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <set>
  7 #include <iostream>
  8 #include <map>
  9 #include <stack>
 10 #include <string>
 11 using namespace std;
 12 #define pi acos(-1.0)
 13 #define eps 1e-6
 14 #define fi first
 15 #define se second
 16 #define lson l,m,rt<<1
 17 #define rson m+1,r,rt<<1|1
 18 #define bug      printf("******")
 19 #define mem(a,b) memset(a,b,sizeof(a))
 20 #define fuck(x)  cout<<"["<<x<<"]"<<endl
 21 #define f(a)     a*a
 22 #define san(n,m) scanf("%d%d",&n,&m)
 23 #define FIN freopen("in.txt","r",stdin)
 24 #define lowbit(x) x&-x
 25 #pragma comment (linker,"/STACK:102400000,102400000")
 26 using namespace std;
 27 const int maxn = 100004;
 28 typedef long long LL;
 29 const int MX = 1050;
 30 const int MXE = 4 * MX * MX;
 31 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
 32 const int INF = 0x3f3f3f;
 33 struct MaxFlow {
 34     struct Edge {
 35         int v, nxt;
 36         LL w;
 37     } E[MXE];
 38     int tot, num, s, t;
 39     int head[MX];
 40     void init() {
 41         memset (head, -1, sizeof (head) );
 42         tot = 0;
 43     }
 44     void add (int u, int v, LL w) {
 45         E[tot] = (Edge) {
 46             v, head[u], w
 47         };
 48         head[u] = tot++;
 49         E[tot] = (Edge) {
 50             u, head[v], 0
 51         };
 52         head[v] = tot++;
 53     }
 54     int  d[MX], vis[MX], gap[MX];
 55     void bfs() {
 56         memset (d, 0, sizeof (d) );
 57         memset (gap, 0, sizeof (gap) );
 58         memset (vis, 0, sizeof (vis) );
 59         queue<int>q;
 60         q.push (t);
 61         vis[t] = 1;
 62         while (!q.empty() ) {
 63             int u = q.front();
 64             q.pop();
 65             for (int i = head[u]; ~i; i = E[i].nxt) {
 66                 int v = E[i].v;
 67                 if (!vis[v]) {
 68                     d[v] = d[u] + 1;
 69                     gap[d[v]]++;
 70                     q.push (v);
 71                     vis[v] = 1;
 72                 }
 73             }
 74         }
 75     }
 76     int last[MX];
 77     LL dfs (int u, LL f) {
 78         if (u == t) return f;
 79         LL sap = 0;
 80         for (int i = last[u]; ~i; i = E[i].nxt) {
 81             int v = E[i].v;
 82             if (E[i].w > 0 && d[u] == d[v] + 1) {
 83                 last[u] = i;
 84                 LL tmp = dfs (v, min (f - sap, E[i].w) );
 85                 E[i].w -= tmp;
 86                 E[i ^ 1].w += tmp;
 87                 sap += tmp;
 88                 if (sap == f) return sap;
 89             }
 90         }
 91         if (d[s] >= num) return sap;
 92         if (! (--gap[d[u]]) ) d[s] = num;
 93         ++gap[++d[u]];
 94         last[u] = head[u];
 95         return sap;
 96     }
 97     LL solve (int st, int ed, int n) {
 98         LL flow = 0;
 99         num = n;
100         s = st;
101         t = ed;
102         bfs();
103         memcpy (last, head, sizeof (head) );
104         while (d[s] < num) flow += dfs (s, INFLL);
105         return flow;
106     }
107 } F;
108 int mp[250][250];
109 int k, c, m;
110 
111 int check(int mid) {
112     F.init();
113     for (int i = 1 ; i <= k ; i++) {
114         F.add(0, i, m);
115         for (int j = k + 1 ; j <= k + c ; j++ )
116             if (mp[i][j] <= mid) F.add(i, j, 1);
117     }
118     for (int i = k + 1 ; i <= k + c ; i++)
119         F.add(i, k + c + 1, 1);
120     if ((int)(F.solve( 0, k + c + 1, k + c + 2)) == c) return 1;
121     return 0;
122 }
123 int main() {
124     while(~scanf("%d%d%d", &k, &c, &m)) {
125         for (int i = 1 ; i <= k + c ; i++)
126             for (int j = 1 ; j <= k + c ; j++) {
127                 scanf("%d", &mp[i][j]);
128                 if (i != j && !mp[i][j]) mp[i][j] = INF;
129             }
130         int num = k + c;
131         for(int q = 1; q <= num; q++)
132             for(int i = 1; i <= num; i++)
133                 for(int j = 1; j <= num; j++)
134                     if(mp[i][j] > mp[i][q] + mp[q][j])   mp[i][j] = mp[i][q] + mp[q][j];
135         int low = 0, high = INF, mid, ans = 0;
136         while(low <= high) {
137             mid = (low + high) >> 1;
138             if (check(mid)) {
139                 ans = mid;
140                 high = mid - 1;
141             } else low = mid + 1;
142         }
143         printf("%d
", ans);
144     }
145     return 0;
146 }

 

 







以上是关于POJ_2112_Optimal Milking 这里有超级快的网络流板子的主要内容,如果未能解决你的问题,请参考以下文章

POJ2112 Optimal Milking —— 二分图多重匹配/最大流 + 二分

POJ 2112 Optimal Milking(二分+最大流)

POJ2112:Optimal Milking(Floyd+二分图多重匹配+二分)

●POJ poj 2112 Optimal Milking

Optimal Milking(POJ2112+二分+Dinic)

POJ 2112 Optimal Milking (二分+最短路+最大流)