Cod sursa(job #3270931)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 24 ianuarie 2025 21:21:53
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <bits/stdc++.h>
using namespace std;

struct Edge {
    int to, rev;   // "to" = nodul spre care duce muchia, "rev" = indexul muchiei inverse
    int cap;       // capacitatea reziduală
};

vector<Edge> adj[100005];  // liste de adiacență (pentru siguranță am pus mai mult decât 1000)
int N, M;

// Funcție pentru a adăuga muchii în graful rezidual
void addEdge(int u, int v, int c) {
    adj[u].push_back({v, (int)adj[v].size(), c});
    adj[v].push_back({u, (int)adj[u].size() - 1, 0});
}

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

    // Deschidem fișierele de intrare/ieșire
    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);

    cin >> N >> M;
    while(M--){
        int x, y, z;
        cin >> x >> y >> z;
        addEdge(x, y, z);
    }

    long long maxFlow = 0;

    // Repetăm BFS cât timp găsim un drum de ameliorare
    while(true){
        vector<int> parent(N+1, -1), edgeIndex(N+1, -1);
        parent[1] = 1;             // marcam sursa ca vizitată
        queue<int> q; q.push(1);

        // BFS pentru a găsi un drum de la 1 la N
        while(!q.empty() && parent[N] == -1){
            int u = q.front();
            q.pop();
            for(int i = 0; i < (int)adj[u].size(); i++){
                auto &e = adj[u][i];
                if(parent[e.to] == -1 && e.cap > 0) {
                    parent[e.to] = u;
                    edgeIndex[e.to] = i;
                    q.push(e.to);
                    if(e.to == N) break;
                }
            }
        }

        // Dacă nu mai există drum, am terminat
        if(parent[N] == -1) break;

        // Aflăm fluxul maxim (bottleneck) pe drumul găsit
        int bottleneck = INT_MAX;
        for(int v = N; v != 1; ){
            int u = parent[v], i = edgeIndex[v];
            bottleneck = min(bottleneck, adj[u][i].cap);
            v = u;
        }

        // Actualizăm fluxul pe drumul găsit și muchiile inverse
        for(int v = N; v != 1; ){
            int u = parent[v], i = edgeIndex[v];
            adj[u][i].cap -= bottleneck;                     // consumăm din capacitate
            adj[v][adj[u][i].rev].cap += bottleneck;         // creștem capacitatea inversă
            v = u;
        }

        maxFlow += bottleneck;
    }

    cout << maxFlow << "\n";
    return 0;
}