Cod sursa(job #2658898)

Utilizator warriorscatsfirestarBarbut-Dica Sami warriorscatsfirestar Data 15 octombrie 2020 13:42:47
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.96 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#include <utility>
#include <limits>
#include <chrono>

using namespace std;
using namespace std::chrono;

using Ip = pair <int, int>;
using Vip = vector <Ip>;
using Vi = vector <int>;
using V2i = vector <Vi>;
using Vi64 = vector <int64_t>;
using Qi = queue <int>;
constexpr int64_t Inf = 1LL * numeric_limits <int>::max ();


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

template <class T = int64_t>
class Dinic {
public:
    Dinic (int n, int s, int t):
        V (n), Source (s), Sink (t) {
        Adj.resize (V), Level.resize (V), Ptr.resize (V);
    }
    void addEdge (int u, int v, T cap) {
        if (u == v) return;
        Edges.emplace_back (u, v, cap);
        Adj[u].emplace_back ((int)Edges.size () - 1);
        Edges.emplace_back (v, u, 0LL);
        Adj[v].emplace_back ((int)Edges.size () - 1);
    }
    T maxFlow () {
        T flow = 0LL;
        while (true) {
            fill (Level.begin (), Level.end (), -1);
            Level[Source] = 0, Q.push (Source);
            if (!bfs ()) break;
            fill (Ptr.begin (), Ptr.end (), 0);
            while (T pushed = dfs (Source, Inf))
                flow += pushed;
        }
        return flow;
    }
private:
    class FlowEdge {
    public:
        FlowEdge (int from, int to, T capacity):
            from (from), to (to), capacity (capacity) {
        }
    private:
        int from, to;
        T capacity, flow = 0LL;
        friend Dinic;
    };
    using Vf = vector <FlowEdge>;
    Vf Edges;
    V2i Adj;
    int V, Source, Sink;
    Vi Level, Ptr;
    Qi Q;
    bool bfs () {
        while (!Q.empty ()) {
            int v = Q.front (); Q.pop ();
            for (const auto& it: Adj[v]) {
                if (Level[Edges[it].to] != -1 || Edges[it].capacity - Edges[it].flow < 1LL) continue;
                Level[Edges[it].to] = Level[v] + 1;
                Q.push (Edges[it].to);
            }
        }
        return Level[Sink] != -1;
    }
    T dfs (int v, T pushed) {
        if (!pushed) return 0LL;
        if (v == Sink) return pushed;
        for (int& cit = Ptr[v]; cit < (int)Adj[v].size (); ++ cit) {
            int it = Adj[v][cit], u = Edges[it].to;
            if (Level[u] != Level[v] + 1 || Edges[it].capacity - Edges[it].flow < 1LL) continue;
            T send = dfs (u, min (pushed, Edges[it].capacity - Edges[it].flow));
            if (!send) continue;
            Edges[it].flow += send;
            Edges[it ^ 1].flow -= send;
            return send;
        }
        return 0LL;
    }
};

int n, m, u, v;
int64_t w;


int main () {
    fin.sync_with_stdio (false), fin.tie (nullptr);
    fout.sync_with_stdio (false), fout.tie (nullptr);

    fin >> n >> m;
    Dinic <int64_t> Graph (n, 0, n - 1);

    for (int i = 0; i < m; ++ i) {
        fin >> u >> v >> w; -- u, -- v;
        Graph.addEdge (u, v, w);
    }

    fout << Graph.maxFlow ();

    fin.close (), fout.close ();
    return 0;
}