Cod sursa(job #2484864)

Utilizator LucaSeriSeritan Luca LucaSeri Data 31 octombrie 2019 18:28:59
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.87 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,tune=native")

using namespace __gnu_pbds;
using namespace std;
     
#define mp make_pair
#define sz(x) (int)((x).size())
#define all(x) (x).begin(),(x).end()
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define eb emplace_back
 
typedef pair< int, int > pii;
typedef pair< long long, long long > pll;
typedef long long ll;
typedef unsigned long long ull;
typedef vector< int > vi;
typedef vector< vi > vvi;
typedef vector< ll > vll;
typedef vector< vll > vvll;
typedef vector< pii > vpii;
typedef vector< vpii > vvpii;
typedef vector< pll > vpll;
typedef long double ld;
typedef vector< ld > vld;
 
const ll MOD2 = 1e9 + 7;
const int MOD = 1e9 + 7;
 
const ull infull = numeric_limits<unsigned long long>::max();
 
void fix(int &x, ll MOD) {
    x = (x % MOD);
    if(x < 0) x += MOD;
    return;
}
 
ll lgput(ll a, ll b, ll MOD) {
    ll ret = 1;
    a %= MOD;
    while(b) {
        if(b&1) ret = ret*a % MOD;
        a = a*a % MOD;
        b >>= 1;
    }
 
    return ret;
}
 
ll inv(ll a, ll MOD) {
    return lgput(a, MOD-2, MOD);
}
 
struct f {
    int a, b;
    f(int _a = 0, int _b = 0) : a(_a) ,b(_b) {}
    ll eval(int x) {
        return 1ll*x*a + b;
    }
};
 
int binarySearch(int x, vi &v) {
    int pos = 0;
    int l = 1, r = sz(v);
    while(l <= r) {
        int m = l + r >> 1;
        if(v[m] <= x) {
            pos = m;
            l = m + 1;
        } else {
            r = m - 1;
        }
    }
 
    return pos;
}

struct Dinic {
    struct Edge {
        int to, flow, next;
        Edge(int _to = 0, int _flow = 0, int _next = 0) {
            to = _to;
            flow = _flow;
            next = _next;
        }
    };

    vector< Edge > edges;
    vector< int > head, act, h;
    int S, D;

    void AddEdge(int a, int b, int f, int revF = 0) {
        edges.emplace_back(b, f, edges.size());
        swap(edges.back().next, head[a]);
        edges.emplace_back(a, revF, edges.size());
        swap(edges.back().next, head[b]);
        return;
    }

    bool bfs() {
        fill(all(h), -1);
        vector< int > q = {S};
        h[S] = 0;
        for(int it = 0; it < q.size() && h[D] == -1; ++it) {
            int node = q[it];
            for(int i = head[node]; i != -1; i = edges[i].next) {
                if(edges[i].flow && h[edges[i].to] == -1) {
                    h[edges[i].to] = h[node] + 1;
                    q.emplace_back(edges[i].to);
                }
            }
        }

        return h[D] != -1;
    }

    int dfs(int node, int flow) {
        if(flow == 0 || node == D) return flow;

        while(act[node] != -1) {
            Edge &e = edges[act[node]];
            int d;
            if(e.flow && h[e.to] == h[node] + 1 && (d = dfs(e.to, min(flow, e.flow))) != 0) {
                e.flow -= d;
                edges[act[node] ^ 1].flow += d;
                return d;
            }

            act[node] = edges[act[node]].next;
        }

        return 0;
    }

    int getFlow() {
        int ret = 0;
        while(bfs()) {
            act = head;
            int d;
            while((d = dfs(S, 1e9)) != 0) ret += d;
        }

        return ret;
    }
    Dinic(int sz = 0, int s = 0, int d = 0) : head(sz + 1, -1), h(sz + 1), S(s), D(d) {}
};


int main() { 
    #ifdef BLAT
        freopen("stdin", "r", stdin);
        freopen("stderr", "w", stderr);
    #else
        FO(maxflow);
    #endif

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(12);
    srand(time(NULL));

    int n, m;
    cin >> n >> m;

    Dinic network(n, 0, n-1);

    for(int i = 0; i < m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        network.AddEdge(a - 1, b - 1, c);
    }

    cout << network.getFlow() << '\n';
    return 0;  
}