POJ-1459 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;
}
posted @ 2012-07-03 10:20  沐阳  阅读(245)  评论(0编辑  收藏  举报