Cod sursa(job #2713452)

Utilizator flibiaVisanu Cristian flibia Data 27 februarie 2021 23:34:49
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.6 kb
// Edmonds-Karp
#include <bits/stdc++.h>
#define ll long long

using namespace std;

ifstream in("maxflow.in");
ofstream out("maxflow.out");

struct Edge {
    int from;
    int to;
    int cap;
    int flow; 
};

struct EKMaxFlow {
    int source;
    int sink;
    vector<Edge> edges;
    vector<vector<pair<int, int> > > v;
    vector<int> path;
    vector<int> seen;
    int N;
    int M;

    EKMaxFlow(int s, int d, int n, int m) : source(s), sink(d), v(n), N(n), M(m), path(n), seen(n) {}

    void addEdge(int from, int to, int cap) {
        edges.push_back({from, to, cap, 0});
        v[from].push_back({to, (int) edges.size() - 1});
        edges.push_back({to, from, 0, 0});
        v[to].push_back({from, (int) edges.size() - 1});
    }

    bool canAugment() {
        queue<int> q;
        q.push(source);
        fill(seen.begin(), seen.end(), 0); 

        while (!q.empty()) {
            int node = q.front();
            q.pop();

            if (node == sink) {
                return true;
            }

            for (auto nxt : v[node]) {
                if (!seen[nxt.first]) {
                    int resCap = edges[nxt.second].cap - edges[nxt.second].flow; 
                
                    if (resCap > 0) {
                        seen[nxt.first] = 1;
                        q.push(nxt.first);
                        path[nxt.first] = nxt.second;
                    }
                }
            }
        }

        return false;
    }

    int maxFlow() {
        int flow = 0;

        while (1) {
            if (canAugment()) {
                int mn = INT_MAX;

                for (int s = sink; s != source; ) {
                    int edgeId = path[s];
                    int resCap = edges[edgeId].cap - edges[edgeId].flow;
                    
                    mn = min(mn, resCap);

                    s = edges[edgeId].from;
                }

                flow += mn;

                for (int s = sink; s != source; ) {
                    int edgeId = path[s];

                    edges[edgeId].flow += mn;
                    edges[edgeId ^ 1].flow -= mn;

                    s = edges[edgeId].from;
                }
            } else {
                break;
            }
        }

        return flow; 
    }
};

int main() {
    int n, m;
    in >> n >> m;
    EKMaxFlow graph(0, n - 1, n, m);

    for (int i = 0, x, y, c; i < m; i++) {
        in >> x >> y >> c;
        x--;
        y--;
        graph.addEdge(x, y, c);
    }

    out << graph.maxFlow();

    return 0;
}