zoukankan      html  css  js  c++  java
  • POJ1459 Power Network 网络流

      题中给出了各种点的定义,其实我们只要建立两个虚拟节点就可以了。一个是源点流到所有的p点,一个是汇点,所有的c点流过去,再求最大流就可以了。当然题中的输入数据比较恶心,这里用了字符串的处理方式来解决。

      代码如下:

    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #define S N
    #define T (N+1)
    #define INF 0x3fffffff
    #define MAXN 105
    using namespace std;
    
    int N, np, nc, M, flow[MAXN][MAXN], cap[MAXN][MAXN];
    int c[MAXN], p[MAXN], Maxflow;
    
    void getint(int &t)
    {
        char c;
        while (c = getchar(), c < '0' || c > '9') {};
        t = c - '0';
        while (c = getchar(), c >= '0' && c <= '9') {
            t = t * 10 + c - '0';
        }
    }
    
    void bfs()
    {
        bool finish = false;
        int pos;
        while (!finish) {
            memset(c, 0, sizeof (c));
            c[S] = INF;  // 虚拟出一个无穷的流从源点流出来
            queue<int>q;
            q.push(S);
            while (!q.empty()) {
                if (c[T]) {
                    break;
                }
                pos = q.front();
                q.pop();
                for (int i = 0; i <= N+1; ++i) {
                    if (!c[i] && flow[pos][i] < cap[pos][i]) {
                    // 前面这个!c[i]很重要,它表示本轮中推送过流量的点不能作为二次推流的节点
                        c[i] = min(cap[pos][i]-flow[pos][i], c[pos]); // 这个值一定是大于零的
                        p[i] = pos;  // 记录路径,以便后面的更新
                        q.push(i);
                    }
                }
            }
            if (c[T] == 0) {  // 本次寻找增广路径失败
                finish = true;
            }
            else {
                Maxflow += c[T];  // 流入到汇点的新流量
                pos = T;
                while (pos != S) {  // 没有回溯到源点
                    flow[p[pos]][pos] += c[T];
                    flow[pos][p[pos]] -= c[T];
                    pos = p[pos];
                }
            }
        }
    }
    
    int main()
    {
        char s[15];
        int x, y, z; // 从0号节点开始,我们可以设置一个N号节点,并建立c到N节点的流量无上限的边
        while (scanf("%d %d %d %d", &N, &np, &nc, &M) == 4) {
            memset(cap, 0, sizeof (cap));
            memset(flow, 0, sizeof (flow));
            Maxflow = 0;
            for (int i = 0; i < M; ++i) {
                getint(x), getint(y), getint(z);
            //    printf("%d %d %d\n", x, y, z);
                cap[x][y] = z;  // 建立边的容量
            }
            for (int i = 0; i < np; ++i) {
                getint(x), getint(y);
                cap[N][x] = y;  // 创建源点
            }
            for (int i = 0; i < nc; ++i) {
                getint(x), getint(y);
                cap[x][N+1] = y;  // 创建汇点
            }
            bfs();
            printf("%d\n", Maxflow);
        }
        return 0;
    }
  • 相关阅读:
    项目UML设计(团队)
    项目选题报告答辩总结
    UIGestureRecognizer 手势
    CGAffineTransform 图像处理类
    block 应用说明
    Runtime-iOS运行时应用篇
    runtime之归档和解档
    Runloop
    加锁处理
    2017年浙江工业大学之江学院程序设计竞赛决赛 I: qwb VS 去污棒(可持久化Trie+离线)
  • 原文地址:https://www.cnblogs.com/Lyush/p/2574289.html
Copyright © 2011-2022 走看看