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.
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.
* 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\n", ans); 144 } 145 return 0; 146 }