Cod sursa(job #3231086)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 24 mai 2024 18:56:41
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.36 kb
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <deque>
#include <queue>

using namespace std;
using ll = long long;

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

class Flow {
private:
    int n, total_flow;
    vector <vector <int>> G;
    vector <Edge> edge_list;
    int s, d;
    vector <int> prv;
    bool bfs() {
        queue <int> q;
        vector <int> dist(n);
        for (int i = 0; i < n; i++) {
            dist[i] = -1;
        }
        dist[s] = 1;
        q.push(s);
        while (!q.empty()) {
            int curr = q.front();
            q.pop();
            for (int edge_ind : G[curr]) {
                Edge curr_edge = edge_list[edge_ind];
                if (dist[curr_edge.nxt] == -1 && curr_edge.flow < curr_edge.cap) {
                    dist[curr_edge.nxt] = dist[curr] + 1;
                    prv[curr_edge.nxt] = edge_ind;
                    q.push(curr_edge.nxt);
                }
            }
        }
        return (dist[d] != -1);
    }
public:
    Flow(int _n) {
        n = _n;
        G.resize(n);
        prv.resize(n);
        s = 0;
        d = n - 1;
    }
    void addEdge(int x, int y, int cap) {
        x--, y--;
        edge_list.push_back({y, 0, cap});
        edge_list.push_back({x, 0, 0});
        G[x].push_back(edge_list.size() - 2);
        G[y].push_back(edge_list.size() - 1);
    }
    void pushFlow() {
        while (bfs()) {
            int min_flow = 1e9;
            for (int nod = d; nod != s; nod = edge_list[prv[nod]^1].nxt) {
                min_flow = min(min_flow, edge_list[prv[nod]].cap - edge_list[prv[nod]].flow);
            }
            for (int nod = d; nod != s; nod = edge_list[prv[nod]^1].nxt) {
                edge_list[prv[nod]].flow += min_flow;
                edge_list[prv[nod] ^ 1].flow -= min_flow;
            }
            total_flow += min_flow;
        }
    }
    int getFlow() {
        return total_flow;
    }
};


int main() {
#ifdef LOCAL
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif // LOCAL
    int n, m;
    cin >> n >> m;
    Flow network(n);
    for (int i = 1; i <= m; i++) {
        int x, y, c;
        cin >> x >> y >> c;
        network.addEdge(x, y, c);
    }
    network.pushFlow();
    cout << network.getFlow();
    return 0;
}