Cod sursa(job #2850898)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 17 februarie 2022 18:26:13
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.15 kb
#include <bits/stdc++.h>

using namespace std;
#ifdef INFOARENA
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
#else
ifstream fin("ciorna.in");
ofstream fout("ciorna.out");
#endif
using ll = long long;
class Flow {
    const ll max_flow = 1e18;
    struct Edge {
        int from, to, cap;
        Edge(int a, int b, int c) : from(a), to(b), cap(c) {}
    };
    int n, k, s, t;
    vector <vector <int>> g;
    vector <int> rem, lvl;
    vector <Edge> edges;
public:
    Flow(int n) : n(n), k(0), s(1), t(n), g(n + 1), rem(n + 1, 0), lvl(n + 1, 0) {}
    void add_edge(int u, int v, int w, int rw = 0) {
        g[u].push_back(k++);
        g[v].push_back(k++);
        edges.emplace_back(u, v, w);
        edges.emplace_back(v, u, rw);
    }
    inline bool bfs() {
        queue <int> q;
        fill(lvl.begin(), lvl.end(), 0);
        for(q.push(s), lvl[s] = 1; !q.empty(); q.pop()) {
            int u = q.front();
            for(int id : g[u]) {
                int v = edges[id].to;
                if(edges[id].cap && !lvl[v]) {
                    q.push(v);
                    lvl[v] = lvl[u] + 1;
                }
            }
        }
        return lvl[t];
    }
    ll dfs(int u, ll flow) {
        if(u == t || !flow) return flow;
        for(int& cid = rem[u]; cid < g[u].size(); cid++) {
            int id = g[u][cid];
            int v = edges[id].to;
            ll f = 0;
            if(edges[id].cap && lvl[v] == lvl[u] + 1) f = dfs(v, min(flow, ll(edges[id].cap)));
            if(!f) continue;
            edges[id].cap -= f;
            edges[id ^ 1].cap += f;
            return f;
        }
        return 0;
    }
    ll dinic(int _s, int _t) {
        s = _s; t = _t;
        ll flow = 0;
        while(bfs()) {
            fill(rem.begin(), rem.end(), 0);
            while(ll f = dfs(s, max_flow))
                flow += f;
        }
        return flow;
    }
};

int main()
{
    int n, m, u, v, w;
    fin >> n >> m;
    Flow F(n);
    for(int i = 1; i <= m; i++)
        fin >> u >> v >> w,
        F.add_edge(u, v, w);
    fout << F.dinic(1, n);
    return 0;
}