PKU 2112 Optimal Milking
时间:2010-10-16 来源:晓天

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
#include<map>
#include<set>
#include<math.h>
using namespace std;
#define N 260
#define E 13000
#define inf 0x7ffffff
#define typec int // type of cost
struct edge {
int x, y, nxt;
typec c;
} bf[E];
int ne, head[N], cur[N], ps[N], dep[N];
int K, C, M;
int g[N][N];
set<int>dis;
int dist[N*N], tot = 0, n;
void addedge(int x, int y, typec c) {
bf[ne].x = x,bf[ne].y = y,bf[ne].c = c;
bf[ne].nxt = head[x],head[x] = ne++;
bf[ne].x = y,bf[ne].y = x,bf[ne].c = 0;
bf[ne].nxt = head[y],head[y] = ne++;
}
typec flow(int n, int s, int t) {
typec tr, res = 0;
int i, j, k, f, r, top;
while (1) {
memset(dep, -1, n * sizeof (int));
for (f = dep[ps[0] = s] = 0, r = 1; f != r;)
for (i = ps[f++], j = head[i]; j; j = bf[j].nxt) {
if (bf[j].c && -1 == dep[k = bf[j].y]) {
dep[k] = dep[i] + 1;
ps[r++] = k;
if (k == t) {
f = r;
break;
}
}
}
if (-1 == dep[t]) break;
memcpy(cur, head, n * sizeof (int));
for (i = s, top = 0;;) {
if (i == t) {
for (k = 0, tr = inf; k < top; ++k)
if (bf[ps[k]].c < tr)
tr = bf[ps[f = k]].c;
for (k = 0; k < top; ++k)
bf[ps[k]].c -= tr, bf[ps[k]^1].c += tr;
res += tr;
i = bf[ps[top = f]].x;
}
for (j = cur[i]; cur[i]; j = cur[i] = bf[cur[i]].nxt)
if (bf[j].c && dep[i] + 1 == dep[bf[j].y]) break;
if (cur[i]) {
ps[top++] = cur[i];
i = bf[cur[i]].y;
} else {
if (0 == top) break;
dep[i] = -1;
i = bf[ps[--top]].x;
}
}
}
return res;
}
void build(int d) {
n = K + C;
ne = 2;
memset(head, 0, sizeof (head));
for (int i = 1; i <= K; i++)
addedge(0, i, M);
for (int i = 1; i <= C; i++)
addedge(K + i, K + C + 1, 1);
for (int i = 0; i < K; i++)
for (int j = K; j < n; j++)
if (g[i][j] <= d) addedge(i + 1, j + 1, 1);
n += 2;
}
void read() {
int i, j, t = K + C;
for (i = 0; i < t; i++)
for (j = 0; j < t; j++) {
scanf("%d", g[i] + j);
if (i != j && g[i][j] == 0) g[i][j] = inf;
}
for (int k = 0; k < t; k++)
for (i = 0; i < t; i++)
for (j = 0; j < t; j++)
if (g[i][k] + g[k][j] < g[i][j]) g[i][j] = g[i][k] + g[k][j];
dis.clear();
for (i = 0; i < t; i++)
for (j = 0; j < t; j++)
if (g[i][j] != inf) dis.insert(g[i][j]);
tot = 0;
for (set<int>::iterator it = dis.begin(); it != dis.end(); it++)
dist[tot++] = *it;
}
void solve() {
int l = 0, r = tot-1, mid;
while (l <= r) {
mid = (l + r) >> 1;
build(dist[mid]);
int ans = flow(n, 0, n - 1);
if (ans == C) r = mid - 1;
else l = mid + 1;
}
printf("%d\n", dist[l]);
}
int main() {
while (scanf("%d%d%d", &K, &C, &M) != EOF) {
read();
solve();
}
return 0;
}
相关阅读 更多 +
排行榜 更多 +