POJ-2112 Optimal Milking二分+ネットワークストリーム
12398 ワード
タイトル:
Kの搾乳ステーション、C頭乳牛があり、各搾乳ステーションは毎日最大M頭乳牛にサービスすることができ、乳牛から乳牛、乳牛から搾乳ステーションまで距離があり、1日ですべての乳牛に搾乳できるマッチング案の中で、最も遠い距離の最小案を選択することができる.
解法:
2分列挙によりエッジの関係を構築し,その後,すべての牛が条件を満たす場合に搾乳できるかどうかをネットワークフローで解いた.
コードは次のとおりです.
Kの搾乳ステーション、C頭乳牛があり、各搾乳ステーションは毎日最大M頭乳牛にサービスすることができ、乳牛から乳牛、乳牛から搾乳ステーションまで距離があり、1日ですべての乳牛に搾乳できるマッチング案の中で、最も遠い距離の最小案を選択することができる.
解法:
2分列挙によりエッジの関係を構築し,その後,すべての牛が条件を満たす場合に搾乳できるかどうかをネットワークフローで解いた.
コードは次のとおりです.
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define inf 0x3fffffff
using namespace std;
int K, C, M, idx;
int G[250][250], head[250], SS = 240, TT = 241;
int dis[250], que[250], front, tail;
struct Node {
int v, next, cap;
}e[60000];
void Floyd() {
for (int k = 1; k <= K+C; ++k) {
for (int i = 1; i <= K+C; ++i) {
for (int j = 1; j <= K+C; ++j) {
if (G[i][k] != -1 && G[k][j] != -1) {
if (G[i][k] + G[k][j] < G[i][j] || G[i][j] == -1) {
// -1 , ,
G[i][j] = G[i][k] + G[k][j];
}
}
}
}
}
/* for (int i = K+1; i <= K+C; ++i) {
for (int j = 1; j <= K; ++j) {
printf("%d %d = %d
", i, j, G[i][j]);
}
}
system("pause");*/
}
void addedge(int x, int v, int cap) {
++idx;
e[idx].v = v, e[idx].cap = cap;
e[idx].next = head[x];
head[x] = idx;
}
bool bfs() {
int pos;
memset(dis, 0xff, sizeof (dis));
dis[SS] = 0;
front = tail = 0;
que[++tail] = SS;
while (front != tail) {
pos = que[++front];
for (int i = head[pos]; i != -1; i = e[i].next) {
int v = e[i].v, cap = e[i].cap;
if (dis[v] == -1 && cap > 0) {
dis[v] = dis[pos] + 1;
que[++tail] = v;
}
}
}
return dis[TT] != -1;
}
int dfs(int u, int flow) {
if (u == TT) {
return flow;
}
int tf = 0, f;
for (int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].v, cap = e[i].cap;
if (dis[v] == dis[u]+1 && cap > 0 && (f = dfs(v, min(cap, flow)))) {
e[i].cap -= f, e[i^1].cap += f;
flow -= f;
tf += f;
}
}
if (tf == 0) dis[u] = -1;
return tf;
}
int Dinic() {
int ret = 0;
while (bfs()) {
ret += dfs(SS, inf);
}
return ret;
}
int bsearch(int l, int r) {
int ret;
while (l <= r) {
int mid = (l + r) >> 1;
memset(head, 0xff, sizeof (head));
idx = -1;
for (int i = 1; i <= K; ++i) { //
addedge(i, TT, M);//
addedge(TT, i, 0);
}
for (int i = K+1; i <= K+C; ++i) { //
addedge(SS, i, 1);
addedge(i, SS, 0);
for (int j = 1; j <= K; ++j) { //
if (G[i][j] != -1 && G[i][j] <= mid) {
addedge(i, j, 1);
addedge(j, i, 0);
}
}
}
if (Dinic() == C) {
ret = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
return ret;
}
int main() {
while (scanf("%d %d %d", &K, &C, &M) == 3) {
// K , C
memset(G, 0xff, sizeof (G));
for (int i = 1; i <= K+C; ++i) {
for (int j = 1; j <= K+C; ++j) {
scanf("%d", &G[i][j]);
if (G[i][j] == 0) G[i][j] = -1;
}
}
Floyd();
// 200,
printf("%d
", bsearch(1, 50000));
}
return 0;
}