zoukankan      html  css  js  c++  java
  • POJ2112 Optimal Milking 最短路+二分构图+网络流

    题意:有C头奶牛,K个挤奶站,每个挤奶器最多服务M头奶牛,奶牛和奶牛、奶牛和挤奶站、挤奶站和挤奶站之间都存在一定的距离。现在问满足所有的奶牛都能够被挤奶器服务到的情况下,行走距离的最远的奶牛的至少要走多远。

    解法:又是一个求最大中的最小问题,很容易想到用二分枚举来得出正确的答案。首先对整个图做一个floyd,求出两两之间的最短路,然后再枚举一个最大距离值进行构边,每次询问是否能够全部奶牛都能够被匹配到。注意:距离为0是当作INF处理,否则在floyd取min的时候要特判。

    代码如下:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    int K, C, M; // K个挤奶器,C头奶牛,每个挤奶器最多M头奶牛共享
    int N;
    int mp[250][250];
    
    struct Edge {
        int v, c, next;    
    };
    
    Edge e[100000];
    int idx, head[250];
    int lv[250];
    int front, tail, que[250];
    const int SS = 0, TT = 248;
    const int INF = 0x3fffffff;
    
    void insert(int a, int b, int c) {
        e[idx].v = b, e[idx].c = c;
        e[idx].next = head[a];
        head[a] = idx++;
    }
    
    void floyd() { // 求出任意两点之间的最短路 
        for (int k = 1; k <= N; ++k) {
            for (int i = 1; i <= N; ++i) {
                if (mp[i][k] == INF || i == k) continue;
                for (int j = 1; j <= N; ++j) {
                    if (mp[k][j] == INF || j == k) continue;
                    mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]);
                }
            }
        }
    }
    
    void build(int threshold) { // 阀值 
        idx = 0;
        memset(head, 0xff, sizeof (head));
        for (int i = 1; i <= K; ++i) {
            insert(SS, i, M);
            insert(i, SS, 0);
            for (int j = K+1; j <= N; ++j) {
                if (mp[i][j] <= threshold) {
                    insert(i, j, 1);
                    insert(j, i, 0);
                }
            }
        }
        for (int i = K+1; i <= N; ++i) {
            insert(i, TT, 1);
            insert(TT, i, 0);
        }
    }
    
    bool bfs() {
        front = tail = 0;
        memset(lv, 0xff, sizeof (lv));
        lv[SS] = 0;
        que[tail++] = SS;
        while (front != tail) {
        //    printf("front = %d, tail = %d\n", front, tail);
            int u = que[front++];
            for (int i = head[u]; i != -1; i = e[i].next) {
                if (!(~lv[e[i].v]) && e[i].c) {
                    lv[e[i].v] = lv[u] + 1;
                    if (e[i].v == TT) return true;
                    que[tail++] = e[i].v;
                }    
            }
        }
        return ~lv[TT];
    }
    
    int dfs(int u, int sup) {
        if (u == TT) return sup;
        int tf = 0, f;
        for (int i = head[u]; i != -1; i = e[i].next) {
            if (lv[u]+1==lv[e[i].v] && e[i].c && (f=dfs(e[i].v, min(e[i].c, sup-tf)))) {
                tf += f;
                e[i].c -= f, e[i^1].c += f;
                if (tf == sup) return sup;
            }
        }
        if (!tf) lv[u] = -1;
        return tf;
    }
    
    int dinic() {
        int ret = 0;
        while (bfs()) {
            ret += dfs(SS, INF);
        }
        return ret;
    } 
    
    int bsearch(int l, int r) {
        int mid, ret;
        while (l <= r) {
            mid = (l + r) >> 1;
            if (build(mid), dinic() == C) {
                ret = mid;
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
        return ret;
    }
    
    int main() {
        while (scanf("%d %d %d", &K, &C, &M) != EOF) {
            N = K+C;    
            memset(mp, 0, sizeof (mp));
            for (int i = 1; i <= N; ++i) {
                for (int j = 1; j <= N; ++j) {
                    scanf("%d", &mp[i][j]);
                    if (!mp[i][j]) mp[i][j] = INF;
                }
            }
            floyd();
            printf("%d\n", bsearch(1, 1000000));
        }
        return 0;
    } 
  • 相关阅读:
    nginx 配置https
    linux 文件上传下载
    linux系统搭建ftp服务器及创建用户使用
    Centos7.3防火墙配置
    CentOS7搭建svn部署项目
    工作中总结的常用PHP代码
    Git查看、创建、上传SSH密钥
    run `npm fund` for details found 16 vulnerabilities (2 low, 8 moderate, 6 high) run `npm audit fix` to fix them, or `npm audit` for details
    获取官方节假日数据的api接口,获取指定日期的节假日数据
    vue-elementUi项目打包后样式入坑
  • 原文地址:https://www.cnblogs.com/Lyush/p/3052077.html
Copyright © 2011-2022 走看看