POJ 2112最短路+二分+网络流
Posted tennant
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2112最短路+二分+网络流相关的知识,希望对你有一定的参考价值。
题目描述:(转)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最短路+二分+网络流的主要内容,如果未能解决你的问题,请参考以下文章
POJ-2112 Optimal Milking(floyd+最大流+二分)