Cod sursa(job #2302955)

Utilizator howsiweiHow Si Wei howsiwei Data 15 decembrie 2018 11:53:12
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.18 kb
#include <iostream>
#include <vector>
#include <queue>
#include <limits>
using namespace std;

#define SZ(a) (int)(a).size()

template<typename F>
class Dinic {
    constexpr static F oo = numeric_limits<F>::max();
    int n;
    vector<vector<pair<int,int>>> al;
    vector<F> caps;
    int s, t;
    vector<int> dist, ial;

    void add_edge1(int u, int v, F c) {
        al[u].emplace_back(SZ(caps), v);
        caps.push_back(c);
    }

    bool bfs() {
        dist.assign(n, n);
        dist[t] = 0;
        queue<int> q;
        q.push(t);
        while (dist[s] == n && !q.empty()) {
            auto v = q.front();
            q.pop();
            for (auto e: al[v]) {
                auto i = e.first;
                auto u = e.second;
                if (dist[u] == n && caps[i ^ 1] > 0) {
                    dist[u] = dist[v] + 1;
                    q.push(u);
                }
            }
        }
        return dist[s] < n;
    }

    F aug(int u, F c0) {
        if (u == t) return c0;
        auto c = c0;
        for (auto &i = ial[u]; i < SZ(al[u]); i++) {
            auto e = al[u][i];
            auto j = e.first;
            auto v = e.second;
            if (dist[v] < dist[u] && caps[j] > 0) {
                if (auto f = aug(v, min(c, caps[j]))) {
                    c -= f;
                    caps[j] -= f;
                    caps[j ^ 1] += f;
                    if (c == 0) break;
                }
            }
        }
        return c0 - c;
    }

public:
    Dinic(int n): n(n) {
        al.resize(n);
    }

    void add_edge(int u, int v, F c) {
        add_edge1(u, v, c);
        add_edge1(v, u, 0);
    }

    F max_flow(int s, int t, F c0 = oo) {
        this->s = s;
        this->t = t;
        auto c = c0;
        while (c > 0 && bfs()) {
            ial.assign(n, 0);
            c -= aug(s, c);
        }
        return c0 - c;
    }
};

int main() {
    cin.sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    Dinic<long long> dinic(n);
    for (int i = 0; i < m; i++) {
        int u, v;
        long long c;
        cin >> u >> v >> c;
        u--; v--;
        dinic.add_edge(u, v, c);
    }
    auto mf = dinic.max_flow(0, n - 1);
    printf("%lld\n", mf);
}