Cod sursa(job #2689559)

Utilizator theodor.moroianuTheodor Moroianu theodor.moroianu Data 21 decembrie 2020 12:56:31
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.96 kb
#include <bits/stdc++.h>
using namespace std;
 
class Dinic {
    struct Edge {
        int to, flow, next;
    };
    vector <Edge> edges;
    vector <int> adia, act, h;
    int S, D;
 
    bool bfs() {
        fill(h.begin(), h.end(), -1);
        h[S] = 0;
        vector <int> q = { S };
        
        for (int it = 0; it < (int)q.size(); it++) {
            int nod = q[it];
            for (int i = adia[nod]; i != -1; i = edges[i].next)
                if (h[edges[i].to] == -1 && edges[i].flow)
                    h[edges[i].to] = 1 + h[nod], q.push_back(edges[i].to);
        }
 
        return h[D] != -1;
    }
 
    int dfs(int nod, int cap_max) {
        if (cap_max == 0 || nod == D)
            return cap_max;
 
        while (act[nod] != -1) {
            Edge& e = edges[act[nod]];
            int d;
            if (h[e.to] == 1 + h[nod] && (d = dfs(e.to, min(cap_max, e.flow))) != 0) {
                /// am trecut d flux
                e.flow -= d;
                edges[act[nod] ^ 1].flow += d;
                return d;
            } 
            act[nod] = edges[act[nod]].next;
        }
        return 0;
    }
 
public:
    Dinic(int n, int S, int D) : adia(n + 1, -1), h(n + 1), S(S), D(D) { }
 
    int GetMaxFlow() {
        int ans = 0, d;
        while (bfs()) {
            act = adia;
            while ((d = dfs(S, 1e9)) != 0)
                ans += d;
        }
        return ans;
    }
 
    void AddEdge(int a, int b, int c) {
        /// de la a la b cu capacitate c
        edges.push_back({ b, c, (int)edges.size() });
        swap(edges.back().next, adia[a]);
        edges.push_back({ a, 0, (int)edges.size() });
        swap(edges.back().next, adia[b]);
    }
};
 
int main()
{
    ifstream in("maxflow.in");
    ofstream out("maxflow.out");
 
    int n, m, a, b, c;
    in >> n >> m;
 
    Dinic dinic(n, 1, n);
 
    while (m--) {
        in >> a >> b >> c;
        dinic.AddEdge(a, b, c);
    }
 
    out << dinic.GetMaxFlow() << '\n';
 
    return 0;
}