2017年3月18日 | ljfcnyali
题目大意
K个产奶机,C头奶牛,每个产奶机最多可供M头奶牛使用;并告诉了产奶机、奶牛之间的两两距离Dij(0<=i,j
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
1
2
题目分析
这道题目直接Floyd求最短距离,然后二分答案乱搞
AC代码
/*************************************************************************
> File Name: POJ2112.cpp
> Author: ljf-cnyali
> Mail: ljfcnyali@gmail.com
> Created Time: 2017/3/18 16:04:33
************************************************************************/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
using namespace std;
#define REP(i, a, b) for(int i = (a), _end_ = (b);i <= _end_; ++ i)
#define mem(a) memset((a), 0, sizeof(a))
#define str(a) strlen(a)
const int maxn = 1010;
int K, C, M, m, n, st, en;
int Map[maxn][maxn], cap[maxn][maxn];
int dis[maxn];
int BFS() {
queue<int> Q;
memset(dis, -1, sizeof(dis));
dis[st] = 0;
Q.push(st);
while(!Q.empty()) {
int x = Q.front();Q.pop();
REP(i, 0, n + 1)
if(cap[x][i] > 0 && dis[i] < 0) {
Q.push(i);
dis[i] = dis[x] + 1;
}
}
if(dis[en] != -1)
return 1;
return 0;
}
int find(int x, int low) {
if(x == en)
return low;
int a = 0;
REP(i, 0, n + 1)
if(cap[x][i] > 0 && dis[x] + 1 == dis[i] && (a = find(i, min(low, cap[x][i])))) {
cap[x][i] -= a;
cap[i][x] += a;
return a;
}
return 0;
}
int dinic() {
int sum, ans = 0;
while(BFS())
while(sum = find(st, 1000000000))
ans += sum;
return ans;
}
void build(int d) {
mem(cap);
n = K + C;
st = 0;
en = n + 1;
REP(i, 1, K)
cap[0][i] += M;
REP(i, K + 1, K + C)
cap[i][en] += 1;
REP(i, 1, K)
REP(j, K + 1, K + C)
if(Map[i][j] <= d)
cap[i][j] += 1;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
while(scanf("%d%d%d", &K, &C, &M) != EOF) {
REP(i, 1, K + C)
REP(j, 1, K + C) {
scanf("%d", &Map[i][j]);
if(Map[i][j] == 0)
Map[i][j] = 1000000000;
}
REP(k, 1, K + C)
REP(i, 1, K + C)
REP(j, 1, K + C)
Map[i][j] = min(Map[i][j], Map[i][k] + Map[k][j]);
int l = 1, r = 1000000000, ans = 1;
while(l <= r) {
int mid = (l + r) / 2;
build(mid);
if(dinic() == C) {
ans = mid;
r = mid - 1;
}
else l = mid + 1;
}
printf("%d\n", ans);
}
return 0;
}