Cod sursa(job #2943820)

Utilizator lucametehauDart Monkey lucametehau Data 21 noiembrie 2022 18:03:31
Problema Flux maxim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.05 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <cstring>
#include <chrono>
#include <cassert>
#include <bitset>
#include <stack>
#include <queue>
#include <iomanip>
#include <random>
#include <string>
#include <complex>
//#include <ext/pb_ds/assoc_container.hpp>

#ifdef _MSC_VER
#  include <intrin.h>
#  define __builtin_popcount __popcnt
#  define __builtin_popcountll __popcnt64
#endif

#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define x first
#define y second
#define ld long double
#define ll long long
#define ull unsigned long long
#define us unsigned short
#define lsb(x) ((x) & (-(x)))
#define pii pair <int, int>
#define pll pair <ll, ll>

using namespace std;

mt19937_64 gen(time(0));
uniform_int_distribution <int64_t> rng;

const int MOD = (int)1e9 + 7;

namespace recurrences {
    // binary exponentiation
    template <int MOD>
    int lgput(int n, int p) {
        int ans = 1, x = n;

        while (p) {
            if (p & 1)
                ans = 1LL * ans * x % MOD;
            x = 1LL * x * x % MOD;
            p >>= 1;
        }

        return ans;
    }

    // modular integer class
    template <int MOD>
    struct Int {
        int x;

        Int() {
            x = 0;
        }

        Int(int _x) {
            if (_x < 0)
                _x += MOD;
            if (_x >= MOD)
                _x -= MOD;
            x = _x;
        }

        friend ostream& operator << (ostream& os, const Int& X) {
            os << (false ? X.x - MOD : X.x);
            return os;
        }

        Int operator + (const Int& other) const {
            int val = x + other.x;

            return (val >= MOD ? val - MOD : val);
        }

        Int operator += (const Int& other) {
            return *this = *this + other;
        }

        Int operator - (const Int& other) const {
            int val = x - other.x;

            return (val < 0 ? val + MOD : val);
        }
        Int operator -= (const Int& other) {
            return *this = *this - other;
        }

        Int operator * (const Int& other) const {
            return 1LL * x * other.x % MOD;
        }

        Int operator *= (const Int& other) {
            return *this = *this * other;
        }

        Int operator / (const Int& other) const {
            return 1LL * x * other.inv() % MOD;
        }

        bool operator == (const Int& other) const {
            return x == other.x;
        }

        bool operator != (const Int& other) const {
            return x != other.x;
        }

        Int pow(int p) const {
            return lgput<MOD>(x, p);
        }

        int inv() const {
            return lgput<MOD>(x, MOD - 2);
        }
    };
};

template <typename T>
T gcd(T a, T b) {
    if (!a)
        return b;
    return gcd<T>(b % a, a);
}

using namespace recurrences;

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

struct Flow {
    int n;

    int cap[1005][1005], prv[1005];
    int best[1005];
    vector <int> g[1005];

    Flow(){}

    void init(int _n) {
        n = _n;
        memset(cap, 0, sizeof(cap));
        memset(prv, 0, sizeof(prv));

        for (int i = 1; i <= n; i++)
            g[i].clear();
    }

    void add_edge(int x, int y, int z) {
        cap[x][y] += z;
        cap[y][x] -= z;

        g[x].push_back(y);
        g[y].push_back(x);
    }

    int bfs(int src, int dst) {
        queue <pii> q;
        for (int i = 1; i <= n; i++)
            best[i] = prv[i] = 0;
        q.push({ int(1e9), src });
        while (!q.empty()) {
            int node = q.front().y, value = q.front().x;
            q.pop();

            if (node == dst)
                return value;

            for (auto& son : g[node]) {
                if (cap[node][son] > 0 && !prv[son]) {
                    prv[son] = node;
                    q.push({ min(value, cap[node][son]), son });
                }
            }
        }

        return 0;
    }

    int max_flow(int src, int dst) {
        int total_flow = 0, flow;
        while(flow = bfs(src, dst)) {
            total_flow += flow;

            int node = dst;
            while (node != src) {
                cap[prv[node]][node] -= flow;
                cap[node][prv[node]] += flow;
                node = prv[node];
            }
        }

        return total_flow;
    }
} flow;

int n, m;

void solve(int test) {
    in >> n >> m;
    flow.init(n);
    for (; m; m--) {
        int x, y, z;
        in >> x >> y >> z;
        flow.add_edge(x, y, z);
    }

    out << flow.max_flow(1, n) << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    srand(time(0));

    int T = 1;
    //cin >> T;

    for (int t = 1; t <= T; t++) {
        solve(t);
    }

    return 0;
}