POJ 2112【最短路+二分+網絡流】
阿新 • • 發佈:2018-04-30
space ret print dinic == con map ini set
題目描述:(轉)k個機器,每個機器最多服務m頭牛。c頭牛,每個牛需要1臺機器來服務。告訴你牛與機器每個之間的直接距離。問:讓所有的牛都被服務的情況下,使走的最遠的牛的距離最短,求這個距離。
#include<stdio.h> #include<string.h> #include<queue> #define maxn 1000 #define INF 0x3f3f3f3f using namespace std; int k, m, c; struct e { int from, to, w, next; }edge[1000000]; int ss, tt; int cur[maxn]; int cont; int head[maxn]; int map[maxn][maxn]; int dis[maxn][maxn]; int divv[maxn]; void add(int u, int v, int w) { edge[cont].from = u; edge[cont].to = v; edge[cont].w = w; edge[cont].next = head[u]; head[u] = cont++; } int makediv() { memset(divv, 0, sizeof(divv)); divv[ss] = 1; queue<int> Q; Q.push(ss); while (!Q.empty()) { int u = Q.front(); if (u == tt) return 1; Q.pop(); for (int i = head[u]; i != -1; i = edge[i].next) { int w = edge[i].w; int v = edge[i].to; if (divv[v] == 0 && w) { divv[v] = divv[u] + 1; Q.push(v); } } } return 0; } int DFS(int u, int maxflow, int tt) { if (u == tt) return maxflow; int ret = 0; for (int &i = cur[u]; i != -1; i = edge[i].next) { int v = edge[i].to; int w = edge[i].w; if (divv[v] == divv[u] + 1 && w) { int f = DFS(v, min(maxflow - ret, w), tt); edge[i].w -= f; edge[i ^ 1].w += f; ret += f; if (ret == maxflow) return ret; } } return ret; } bool Dinic(int mid) { int ans = 0; for (int i = 1; i <= k; i++) { add(ss, i, m); add(i, ss, 0); } for (int i = k + 1; i <= k + c; i++) { add(i, tt, 1); add(tt, i, 1); } for (int i = k + 1; i <= k + c; i++) { for (int j = 1; j <= k; j++) { if (map[i][j] <= mid) { add(j, i, 1); add(i, j, 0); } } } while (makediv() == 1) { memcpy(cur, head, sizeof(head)); ans += DFS(ss, INF, tt); } if (ans == c) return true; else return false; } void Solve() { int l = 1, r = 10000; int mid; while (l <= r) { cont = 0; memset(head, -1, sizeof(head)); mid = (l + r) / 2; if (Dinic(mid)) { r = mid - 1; } else { l = mid + 1; } } printf("%d\n", l); } void floyd() { for (int t = 1; t <= k + c; t++) for (int i = 1; i <= k + c; i++) { for (int j = 1; j <= k + c; j++) { if (map[i][t] + map[t][j] < map[i][j]) map[i][j] = map[i][t] + map[t][j]; } } } int main(void) { while (~scanf("%d%d%d", &k, &c, &m)) { ss = 0; tt = k + c + 1; for (int i = 1; i <= k + c; i++) { for (int j = 1; j <= k + c; j++) { int w; scanf("%d", &w); if (i != j && !w) map[i][j] = INF; else map[i][j] = w; } } floyd(); Solve(); } return 0; }
POJ 2112【最短路+二分+網絡流】