Cod sursa(job #1862440)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 29 ianuarie 2017 22:29:39
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.74 kb
#include <bits/stdc++.h>

#define fi first
#define se second

using namespace std;

template <bool isDirected, typename capType>
class flowNetwork {
    private:
        class Edge {
            public:
                int to;
                int c;
                int f;

                Edge(
                  int __to = 0,
                  int __c = 0,
                  int __f = 0
                ) {
                    to = __to;
                    c = __c;
                    f = __f;
                }
        };

        static const capType Inf = numeric_limits <capType> :: max();
        int n;
        int m;
        int s;
        int t;
        vector <int> p;
        vector <int> d;
        vector <Edge> e;
        vector <vector <int>> g;

        inline void link(int x, int y, capType c) {
            for (int i = 0; i < 2; i++) {
                e.push_back(Edge(y, c, 0));
                g[x].push_back(m++);
                c *= (isDirected == false);
                swap(x, y);
            }
        }

        inline bool bfs() {
            d = vector <int>(n, -1);
            queue <int> q;
            d[s] = 0;
            for (q.push(s); q.empty() == false; q.pop()) {
                int x = q.front();
                for (int i: g[x]) {
                    if (e[i].f < e[i].c) {
                        int y = e[i].to;
                        if (d[y] == -1) {
                            d[y] = d[x] + 1;
                            q.push(y);
                        }
                    }
                }
            }
            return (d[t] != -1);
        }

        capType dfs(int x, capType f) {
            if (x == t) {
                return f;
            }
            else {
                if (f == 0) {
                    return f;
                }
                else {
                    while (p[x] < g[x].size()) {
                        int i = g[x][p[x]];
                        int y = e[i].to;
                        if (d[y] == d[x] + 1) {
                            capType fn = dfs(y, min(f, e[i].c - e[i].f));
                            if (fn > 0) {
                                e[i].f += fn;
                                e[i ^ 1].f -= fn;
                                return fn;
                            }
                        }
                        p[x]++;
                    }
                    return 0;
                }
            }
        }

    public:
        flowNetwork(
          int __n,
          int __s,
          int __t,
          const vector <pair <capType, pair <int, int>>> &edges
        ) {
            m = 0;
            n = __n;
            s = __s;
            t = __t;
            g = vector <vector <int>>(n, vector <int>());
            for (const auto &edge: edges) {
                link(edge.se.fi, edge.se.se, edge.fi);
            }
        }

        capType solve() {
            capType f = 0;
            bool done = false;
            do {
                if (bfs() == false) {
                    done = true;
                }
                else {
                    p = vector <int>(n, 0);
                    capType fn;
                    do {
                        fn = dfs(s, Inf);
                        f += fn;
                    } while (fn != 0);
                }
            } while (done == false);
            return f;
        }
};

int n;
int m;
vector <pair <int, pair <int, int>>> edges;

int main() {
    ifstream cin("maxflow.in");
    ofstream cout("maxflow.out");

    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int x;
        int y;
        int c;
        cin >> x >> y >> c;
        x--; y--;
        edges.push_back({c, {x, y}});
    }

    cout << flowNetwork <true, int> (n, 0, n - 1, edges).solve() << "\n";
    return 0;
}