Cod sursa(job #1333491)

Utilizator andreiiiiPopa Andrei andreiiii Data 3 februarie 2015 11:15:51
Problema Flux maxim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.74 kb
#include <bits/stdc++.h>
using namespace std;

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

        }

    void addEdge(int x, int y, int cap, int flow = 0) {
        G[x].push_back(edges.size());
        edges.push_back(Edge(y, cap, flow));
        G[y].push_back(edges.size());
        edges.push_back(Edge(x, 0, -flow));
    }

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

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

            if (node == D) continue;

            for (int p: G[node]) {
                if (edges[p].cap == edges[p].flow || father[edges[p].to] != -1) continue;
                father[edges[p].to] = p ^ 1;
                Q.push(edges[p].to);
            }
        }
        return father[D] != -1;
    }

    void dfsClear(int node) {
        father[node] = 0;
        for (int p: G[node]) {
            edges[p].flow = 0;
            if (father[edges[p].to] != -1)
                dfsClear(edges[p].to);
        }
    }
};

MaxFlowNetwork G(1);

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

    int N, M;
    fin >> N >> M;

    G = 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();
}