POJ2112 Dinic + Floyd

来源:互联网 发布:苏州淘宝美工招聘 编辑:程序博客网 时间:2024/06/06 00:42

2017年3月18日 | ljfcnyali
题目大意
K个产奶机,C头奶牛,每个产奶机最多可供M头奶牛使用;并告诉了产奶机、奶牛之间的两两距离Dij(0<=i,j

2 3 20 3 2 1 13 0 3 2 02 3 0 1 01 2 1 0 21 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;}

本文转自:http://ljf-cnyali.cn/index.php/archives/82

原创粉丝点击