Cod sursa(job #3192906)

Utilizator MatteoalexandruMatteo Verzotti Matteoalexandru Data 13 ianuarie 2024 14:31:12
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#include <bits/stdc++.h>
#ifdef BLAT
    #include "debug/debug.hpp"
#else
    #define debug(x...)
#endif

using namespace std;

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

const int INF = 1e9;

class Dinic {
private:
    struct Edge {
        int from, to, cap, nxt;
    };

    int n;
    vector<Edge> e;
    vector<int> g, rem, lev;

public:
    Dinic(int _n) : n(_n) {
        g.resize(_n, -1);
        rem.resize(_n);
        lev.resize(_n);
    }

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

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

    bool bfs(int s, int t) {
        fill(lev.begin(), lev.end(), INF);

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

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

            for (int i = g[from]; i != -1; i = e[i].nxt) {
                Edge edge = e[i];

                if (edge.cap && lev[edge.to] > 1 + lev[edge.from]) {
                    lev[edge.to] = 1 + lev[edge.from];
                    q.push(edge.to);
                }
            }
        }

        return lev[t] != INF;
    }

    int dfs(int node, int need, int t) {
        if (need == 0 || node == t)
            return need;
        
        int curr_flow = 0;

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

            if (lev[edge.to] == 1 + lev[edge.from] && edge.cap) {
                int flow = dfs(edge.to, min(need, edge.cap), t);

                e[it].cap -= flow;
                e[it ^ 1].cap += flow;

                curr_flow += flow;
                need -= flow;

                if (need == 0)
                    break;
            }
        }

        return curr_flow;
    }

    int maxFlow(int s, int t) {
        int flow = 0;
        while (bfs(s, t)) {
            rem = g;
            flow += dfs(s, INF, t);
        }

        return flow;
    }
};

int main() {
    int n, m;
    in >> n >> m;

    Dinic g(1 + n);
    for (int i = 0; i < m; i++) {
        int u, v, w;
        in >> u >> v >> w;
        g.addEdge(u, v, w);
    }

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