Cod sursa(job #3309096)

Utilizator alesiodemiriAlesio Demiri alesiodemiri Data 31 august 2025 23:32:34
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.99 kb
#include <iostream>
#include <queue>
#include <algorithm>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <iomanip>
#include <climits>

using namespace std;

struct Edge {
    int end;
    int flow;
    int capacity;

    Edge(int end, int flow, int capacity): end(end), flow(flow), capacity(capacity){}
};

#define ll long long

int n,m;
vector<vector<Edge>> graph;
vector<int> degIn;
vector<int> degOut;
int source = 0;
int drain = 0;

void ReadData() {
    cin >> n >> m;
    degIn.resize(n, 0);
    degOut.resize(n, 0);

    graph.resize(n, vector<Edge>());
    int start, end, capacity;
    for(int i = 0; i < m; ++i){
        cin >> start >> end >> capacity;
        start--;end--;
        graph[start].push_back(Edge(end, 0, capacity));
        graph[end].push_back(Edge(start, 0, 0));
        degOut[start]++;
        degIn[end]++;
    }
}

bool bfs(int s, int t, vector<int>& parent) {
    fill(parent.begin(), parent.end(), -1);
    queue<int> q;
    q.push(s);
    parent[s] = -2; // mark as visited

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

        for (int i = 0; i < graph[node].size(); i++) {
            Edge &e = graph[node][i];
            if (parent[e.end] == -1 && e.flow < e.capacity) {
                parent[e.end] = node; // remember the path
                if (e.end == t) return true; // reached sink
                q.push(e.end);
            }
        }
    }
    return false;
}

void Solve() {
    for(int i = 0; i < n; i++){
        if (degIn[i] == 0) source = i;
        if (degOut[i] == 0) drain = i;  
    } 

    int maxFlow = 0;
    vector<int> parent(n);

    while (bfs(source, drain, parent)) {
        int minFlow = INT_MAX;

        // find minimum residual capacity along path
        for (int v = drain; v != source; ) {
            int u = parent[v];
            for (Edge &e : graph[u]) {
                if (e.end == v && e.flow < e.capacity) {
                    minFlow = min(minFlow, e.capacity - e.flow);
                    break;
                }
            }
            v = u;
        }

        // update residual graph
        for (int v = drain; v != source; ) {
            int u = parent[v];

            for (Edge &e : graph[u]) {
                if (e.end == v) {
                    e.flow += minFlow;
                    break;
                }
            }

            for (Edge &e : graph[v]) {
                if (e.end == u) {
                    e.flow -= minFlow;
                    break;
                }
            }

            v = u;
        }

        maxFlow += minFlow;
    }

    cout << maxFlow << "\n";
    

}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);

    int t = 1;
    // cin >> t; // Uncomment for multiple test cases
    while (t--) {
        ReadData();
        Solve();   
    }
    return 0;
}