Cod sursa(job #1333535)

Utilizator andreiiiiPopa Andrei andreiiii Data 3 februarie 2015 12:14:31
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.24 kb
#include <bits/stdc++.h>
using namespace std;

class MaxFlowNetwork {
private:
    typedef long long i64;
    class Edge {
    public:
        int to;
        int cap, flow;
        Edge* rev;
        Edge(const int _to, const int _cap, const int _flow):
            to(_to), cap(_cap), flow(_flow) {}
    };
public:
    MaxFlowNetwork(const int N):
        G(vector<vector<Edge*>>(N)), father(vector<Edge*>(N)), NIL(new Edge(0, 0, 0)) {

        }
    ~MaxFlowNetwork() {
        for (auto& p: G)
            for (Edge* l: p)
                delete l;
        delete NIL;
    }

    void addEdge(int x, int y, int cap, int flow = 0) {
        Edge* add = new Edge(y, cap, flow);
        Edge* rev = new Edge(x, 0, -flow);
        add->rev = rev; rev->rev = add;
        G[x].push_back(add);
        G[y].push_back(rev);
    }

    int maxFlow(int S, int D, bool clearFlow = true) {
        int flow = 0;
        for (int i = 0; i < int(G.size()); ++i) {
            vector<Edge*> zero, nonZero;
            for (Edge* p: G[i])
                if (p->cap == 0) zero.push_back(p);
                else nonZero.push_back(p);
            G[i] = nonZero;
            for (Edge* p: zero) G[i].push_back(p);
        }
        while (bfs(S, D)) {
            for (Edge* p: G[D]) {
                if (p->rev->cap == p->rev->flow || father[p->to] == NULL) continue;
                father[D] = p;
                int fmin = MaxFlowNetwork::Inf;
                for (int i = D; i != S; i = father[i]->to)
                    fmin = min(fmin, father[i]->rev->cap - father[i]->rev->flow);
                flow += fmin;
                for (int i = D; i != S; i = father[i]->to) {
                    father[i]->rev->flow += fmin;
                    father[i]->flow -= fmin;
                }
            }
        }
        if (clearFlow) {
            fill(father.begin(), father.end(), (Edge*)NULL);
            dfsClear(S);
        }
        return flow;
    }
private:
    const static int Inf = 0x3f3f3f3f;
    vector<vector<Edge*>> G;
    vector<Edge*> father;
    Edge* NIL;

    bool bfs(int S, int D) {
        fill(father.begin(), father.end(), (Edge*)NULL);
        queue<int> Q;
        Q.push(S);
        father[S] = NIL;
        while (!Q.empty()) {
            int node = Q.front();
            Q.pop();

            if (node == D) continue;

            for (Edge* p: G[node]) {
                if (p->cap > p->flow && father[p->to] == NULL) {
                    father[p->to] = p->rev;
                    Q.push(p->to);
                }
            }
        }
        return father[D] != NULL;
    }

    void dfsClear(int node) {
        father[node] = NIL;
        for (Edge* p: G[node]) {
            p->flow = 0;
            if (father[p->to] != NIL)
                dfsClear(p->to);
        }
    }
};


int main()
{
    ifstream fin("maxflow.in");
    ofstream fout("maxflow.out");

    int N, M;
    fin >> N >> M;
    unique_ptr<MaxFlowNetwork> G(new MaxFlowNetwork(N));

    while (M--) {
        int x, y, cap;
        fin >> x >> y >> cap;
        G->addEdge(x - 1, y - 1, cap);
    }

    fout << G->maxFlow(0, N - 1, false) << '\n';

    fin.close();
    fout.close();
}