Cod sursa(job #3231091)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 24 mai 2024 19:04:28
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.44 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, -1);
        dist[s] = 0;
        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()) {
            for (int edge_ind : G[d]) {
                Edge last_edge = edge_list[edge_ind];
                int min_flow = 1e9;
                prv[d] = edge_ind;
                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() {
    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);
    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;
}