zoukankan      html  css  js  c++  java
  • POJ_2112 Optimal Milking(网络流)

      /*昨晚写把Dinic写错了,一直不出结果,也没调出来,睡觉之前猛然想起来,少了
    一个break,造成死循环了。今天把那地方改过来,交上去WA。然后又重新敲之,TLE。
    后来检查了一遍,发现是Floyd写错了,改过后终于过了,发现网络流太容易错了。

      思路:

    1、用Floyd把每个奶牛到每个挤奶机的距离算出来,然后问题就变成了已知c头奶牛到
    k个挤奶机的距离,求走最远距离的牛走的路程mindis最小是多少。

    2、然后建网络流模型,每头奶牛和挤奶机都是一个结点。设一个源点s,s到c头奶牛
    的容量都记为1,k个挤奶机到汇点T的距离都记为m。

    3、先假设一个mindis的值,然后当奶牛到挤奶机的距离小于mindis时,奶牛结点到挤
    奶机结点的容量为1。

    4、用一次Dinic()求出最大流,如果 Dinic() == c,mindis减小重复3步骤,直到找
    到最小距离。


    My Code:
    */

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>

    using namespace std;

    const int N = 300;
    const int inf = 0x6fffffff;

    int map[N][N];
    int g[N][N];
    int layer[N];
    bool vis[N];
    int T, n;

    bool Layer() {
    int i, v;
    deque<int> q;
    memset(layer, -1, sizeof(layer));
    q.push_back(0);
    layer[0] = 0;
    while(!q.empty()){
    v = q.front();
    q.pop_front();
    for(i = 0; i <= T; i++) {
    if(g[v][i] > 0 && layer[i] == -1) {
    layer[i] = layer[v] + 1;
    if(i == T) {q.clear(); return true;}
    else q.push_back(i);
    }
    }
    }
    return false;
    }

    int Dinic() {

    deque<int> q;
    int v, i, vs, ve, min, min_s, sum = 0;
    while(Layer()) {
    memset(vis, false, sizeof(vis));
    vis[0] = true;
    q.push_back(0);
    while(!q.empty()) {
    v = q.back();
    if(v == T) {
    min = inf;
    for(i = 1; i < q.size(); i++) {
    vs = q[i-1]; ve = q[i];
    if(g[vs][ve] > 0 && min > g[vs][ve]) {
    min = g[vs][ve];
    min_s = vs;
    }
    }
    sum += min;
    for(i = 1; i < q.size(); i++) {
    vs = q[i-1]; ve = q[i];
    if(g[vs][ve] > 0) {
    g[vs][ve] -= min;
    g[ve][vs] += min;
    }
    }
    while(!q.empty() && q.back() != min_s) {
    vis[q.back()] = false;
    q.pop_back();
    }
    } else {
    for(i = 0; i <= T; i++) {
    if(g[v][i] > 0 && !vis[i] && layer[i] == layer[v] + 1) {
    vis[i] = true;
    q.push_back(i);
    break;
    }
    }
    if(i > T) q.pop_back();
    }
    }
    }
    return sum;
    }

    void built(int dis, int k, int m) {
    int i, j;
    memset(g, 0, sizeof(g));
    for(i = k+1; i <= n; i++) {
    g[0][i] = 1;
    for(j = 1; j <= k; j++) {
    if(map[i][j] <= dis) g[i][j] = 1;
    }
    }
    for(i = 1; i <= k; i++) {
    g[i][T] = m;
    }
    }

    void Floyd() {
    int i, j, k;
    for(k = 1; k <= n; k++) {
    for(i = 1; i <= n; i++) {
    for(j = 1; j <= n; j++) {
    if(i != j && map[i][k] != inf && map[k][j] != inf && map[i][k] + map[k][j] < map[i][j]){
    map[i][j] = map[i][k] + map[k][j];
    }
    }
    }
    }
    }

    int main() {
    //freopen("data.in", "r", stdin);

    int k, c, m, i, j, ans;
    int l, r, mid;

    scanf("%d%d%d", &k, &c, &m);{
    n = k + c; T = n + 1;
    memset(map, 0, sizeof(map));

    for(i = 1; i <= n; i++) {
    for(j = 1; j <= n; j++) {
    scanf("%d", &map[i][j]);
    if(map[i][j] == 0) map[i][j] = inf;
    }
    }
    Floyd();
    l = 0, r = inf - 10;
    while(l < r) {
    mid = (l + r) >> 1;

    built(mid, k, m);
    ans = Dinic();
    //printf("%d %d\n", ans, mid);
    if(ans == c) r = mid;
    else l = mid + 1;
    }
    printf("%d\n", r);
    }
    return 0;
    }
  • 相关阅读:
    关于基础排序算法的思考--插入排序
    关于购物车的多层复选全选
    随便写写
    第一篇小博文
    C# 遍历目录下所有文件方法
    C#驱动MongoDB官方中查询条件Query用法
    mongodb 修改远程连接
    Python 爬虫练习低调163疫情数据辽宁地图
    jquery easyui datagrid drop事件执行顺序
    https request报错 ServicePointManager.SecurityProtocol 搞定
  • 原文地址:https://www.cnblogs.com/vongang/p/2249485.html
Copyright © 2011-2022 走看看