Cod sursa(job #2806976)

Utilizator MatteoalexandruMatteo Verzotti Matteoalexandru Data 23 noiembrie 2021 11:10:50
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.02 kb
/*
                `-/oo+/-   ``
              .oyhhhhhhyo.`od
             +hhhhyyoooos. h/
            +hhyso++oosy- /s
           .yoooossyyo:``-y`
            ..----.` ``.-/+:.`
                   `````..-::/.
                  `..```.-::///`
                 `-.....--::::/:
                `.......--::////:
               `...`....---:::://:
             `......``..--:::::///:`
            `---.......--:::::////+/`
            ----------::::::/::///++:
            ----:---:::::///////////:`
            .----::::::////////////:-`
            `----::::::::::/::::::::-
             `.-----:::::::::::::::-
               ...----:::::::::/:-`
                 `.---::/+osss+:`
                   ``.:://///-.
*/
#include <bits/stdc++.h>
#define debug(x) cerr << #x << " " << x << '\n'
#define debugsp(x) cerr << #x << " " << x << ' '

using namespace std;

ifstream in ("maxflow.in");
ofstream out ("maxflow.out");

const int INF = 2e9;

class Dinic {
private:

    struct Edge {
        int from, to, cap, nxt;
    };

    int n;
    vector <int> lev, rem, graph;
    vector <Edge> edges;

public:

    Dinic (int n) : n(n) {
        graph.resize(1 + n, -1);
        lev.resize(1 + n);
        rem.resize(1 + n);
    }

    void addEdge (int from, int to, int w) {
        edges.push_back(Edge {from, to, w, graph[from]});
        graph[from] = edges.size() - 1;

        edges.push_back(Edge {to, from, 0, graph[to]});
        graph[to] = edges.size() - 1;
    }

    bool bfs() { 
        fill (lev.begin(), lev.end(), 0);

        queue <int> q;
        q.push(1);
        lev[1] = 1;

        while (!q.empty()) {
            int from = q.front();
            q.pop();
            
            for (int i = graph[from]; i != -1; i = edges[i].nxt) {
                Edge e = edges[i];
                
                if (e.cap && lev[e.to] == 0) {
                    lev[e.to] = 1 + lev[e.from];
                    q.push(e.to);
                }
            }
        }

        return (lev[n] > 0);
    }
    
    int dfs (int node, int need) {
        if (need == 0) return 0;
        if (node == n) return need;

        int curr_flow = 0;

        for (int &it = rem[node]; it != -1; it = edges[it].nxt) {
            Edge e = edges[it];

            if (lev[e.to] == 1 + lev[node] && e.cap > 0) {
                int flow = dfs (e.to, min (need , e.cap));
                
                edges[it].cap -= flow;
                edges[it ^ 1].cap += flow;

                curr_flow += flow;
                need -= flow;

                if (need == 0)
                    break;
            }
        }

        return curr_flow;
    }

    int maxFlow() {
        int ans = 0;

        while (bfs() == true) {
            rem = graph;

            ans += dfs (1, INF);
        }

        return ans;
    }
};

int main() {
    int n, m;

    in >> n >> m;

    Dinic g (n);

    for (int i = 1; i <= m; i++) {
        int x, y, w;
        in >> x >> y >> w;
        g.addEdge(x, y, w);
    }

    out << g.maxFlow() << '\n';
    in.close();
    out.close();
    return 0;
}