POJ 1459 Power Network(最大流入门)

题意:

有一个电力网络,有发电厂,有变压器,又用户,图的意思是容量,以及流量,还有边,以及边的容量,流量。求解用户的最大使用量。

思路:

最大流入门,采用 SAP + GAP优化,模板是采用刘汝佳算法入门经典:训练指南上面的。

 

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

structedge {
    int from, to, cap, flow;
    edge(int _from, int _to, int _cap, int _flow)
        : from(_from), to(_to), cap(_cap), flow(_flow) {}
};

const int MAXN = 110;
const int INFS = 0x3fffffff;

vector<edge> edges;
vector<int> G[MAXN];
int p[MAXN], gap[MAXN], dist[MAXN], cur[MAXN];

int augment(int s, int t) {
    int x = t, aug = INFS;
    while (x != s) {
        edge& e = edges[p[x]];
        aug = min(aug, e.cap - e.flow);
        x = edges[p[x]].from;
    }
    x = t;
    while (x != s) {
        edges[p[x]].flow += aug;
        edges[p[x]^1].flow -= aug;
        x = edges[p[x]].from;
    }
    return aug;
}

int sap(int s, int t, int n) {
    int maxflow = 0;

    memset(gap, 0, sizeof(int)*(n+1));
    memset(cur, 0, sizeof(int)*(n+1));
    memset(dist, 0, sizeof(int)*(n+1));

    gap[0] = n;
    int x = s;
    while (dist[s] < n) {
        if (x == t) {
            maxflow += augment(s, t);
            x = s;
        }
        bool flag = false;
        for (int i = cur[x]; i < G[x].size(); i++) {
            edge& e = edges[G[x][i]];
            if (e.cap > e.flow && dist[x] == dist[e.to] + 1) {
                flag = true;
                p[e.to] = G[x][i];
                cur[x] = i;
                x = e.to;
                break;
            }
        }
        if (!flag) {
            int m = n - 1;
            for (int i = 0; i < G[x].size(); i++) {
                edge& e = edges[G[x][i]];
                if (e.cap > e.flow) 
                    m = min(m, dist[e.to]);
            }
            if (--gap[dist[x]] == 0)  break;
            gap[dist[x] = m+1] += 1;
            cur[x] = 0;
            if (x != s) x = edges[p[x]].from;
        }
    }
    return maxflow;
}

void addedge(int u, int v, int cap) {
    edges.push_back(edge(u, v, cap, 0));
    edges.push_back(edge(v, u, 0, 0));
    int m = edges.size();
    G[u].push_back(m - 2);
    G[v].push_back(m - 1);
}

int main() {
    int n, np, nc, m;
    while (scanf("%d", &n) != EOF) {
        scanf("%d%d%d", &np, &nc, &m);
        
        edges.clear();
        for (int i = 0; i <= n+2; i++)
            G[i].clear();

        int u, v, cap;
        for (int i = 0; i < m; i++) {
            scanf(" (%d,%d)%d ", &u, &v, &cap);
            addedge(u + 2, v + 2, cap);
        }
        for (int i = 0; i < np; i++) {
            scanf(" (%d)%d ", &v, &cap);
            addedge(1, v + 2, cap);
        }
        for (int i = 0; i < nc; i++) {
            scanf(" (%d)%d ", &u, &cap);
            addedge(u + 2, n + 2, cap);
        }
        printf("%d\n", sap(1, n + 2, n + 2));
    }
    return 0;
}
posted @ 2013-04-10 11:20  kedebug  阅读(234)  评论(0编辑  收藏  举报