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;

}

你可能感兴趣的:(NetWork)