Cod sursa(job #1991907)

Utilizator retrogradLucian Bicsi retrograd Data 18 iunie 2017 17:26:23
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.35 kb
#include <bits/stdc++.h>

using namespace std;

struct Dinic {
    struct Edge {
        int to, cap, flow, nxt;
    };

    vector<Edge> edges;
    vector<int> graph, at, dist;
    int src = 0, dest = 1;

    Dinic(int n, int m = 0) : graph(n, -1), dist(n, -1) {
        edges.reserve(2*m);
    }

    void m_add_edge(int from, int to, int cap) {
        edges.push_back(Edge {to, cap, 0, graph[from]});
        graph[from] = edges.size() - 1;
    }
    void add_edge(int from, int to, int cap) {
        m_add_edge(from, to, cap);
        m_add_edge(to, from, 0);
    }

    void set_source_sink(int src, int dest) {
        this->src = src; this->dest = dest;
    }

    bool bfs(int step) {
        queue<int> q;
        fill(dist.begin(), dist.end(), -1);
        dist[src] = 0;
        q.push(src);

        while (!q.empty()) {
            int node = q.front(); q.pop();
            for (int i = graph[node]; i >= 0; i = edges[i].nxt) {
                const auto &e = edges[i];
                if (dist[e.to] == -1 && e.flow + step <= e.cap) {
                    dist[e.to] = dist[node] + 1;
                    q.push(e.to);
                }
            }
        }

        return dist[dest] != -1;
    }

    int dfs(int node, int flow) {
        if (flow == 0) return 0;
        if (node == dest) return flow;

        while (at[node] != -1) {
            int eid = at[node];
            const auto &e = edges[eid];

            if (dist[e.to] == dist[node] + 1) {
                if (int ret = dfs(e.to, min(flow, e.cap - e.flow))) {
                    edges[eid].flow += ret;
                    edges[eid^1].flow -= ret;
                    return ret;
                }
            }

            at[node] = e.nxt;
        }

        return 0;
    }

    int compute() {
        int ret = 0, step = (1 << 30);

        while (step > 0) {
            if (!bfs(step)) step /= 2;
            else {
                at = graph;
                while (int flow = dfs(src, step))
                    ret += flow;
            }
        }

        return ret;
    }

};

int main() {
    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);

    int n, m; cin >> n >> m;
    Dinic D(n, m);
    while (m--) {
        int a, b, c; cin >> a >> b >> c;
        D.add_edge(a - 1, b - 1, c);
    }
    D.set_source_sink(0, n - 1);

    cout << D.compute() << endl;

    return 0;
}