Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // #define _CRT_SECURE_NO_WARNINGS
- // ░░░░░░░▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄░░░░░░
- // ░░░░░░█░░▄▀▀▀▀▀▀▀▀▀▀▀▀▀▄░░█░░░░░
- // ░░░░░░█░█░▀░░░░░▀░░▀░░░░█░█░░░░░
- // ░░░░░░█░█░░░░░░░░▄▀▀▄░▀░█░█▄▀▀▄░
- // █▀▀█▄░█░█░░▀░░░░░█░░░▀▄▄█▄▀░░░█░
- // ▀▄▄░▀██░█▄░▀░░░▄▄▀░░░░░░░░░░░░▀▄
- // ░░▀█▄▄█░█░░░░▄░░█░░░▄█░░░▄░▄█░░█
- // ░░░░░▀█░▀▄▀░░░░░█░██░▄░░▄░░▄░███
- // ░░░░░▄█▄░░▀▀▀▀▀▀▀▀▄░░▀▀▀▀▀▀▀░▄▀░
- // ░░░░█░░▄█▀█▀▀█▀▀▀▀▀▀█▀▀█▀█▀▀█░░░
- // ░░░░▀▀▀▀░░▀▀▀░░░░░░░░▀▀▀░░▀▀░░░░
- #include <algorithm>
- #include <array>
- #include <bitset>
- #include <chrono>
- #include <cmath>
- #include <cstdio>
- #include <cstring>
- #include <ctime>
- #include <deque>
- #include <fstream>
- #include <iostream>
- #include <map>
- #include <numeric>
- #include <queue>
- #include <random>
- #include <set>
- #include <stack>
- #include <string>
- #include <unordered_map>
- #include <unordered_set>
- #include <vector>
- //#pragma GCC optimize("Ofast,inline,unroll-loops,no-stack-protector,O2")
- //#pragma GCC target("avx,avx2,fma")
- using namespace std;
- #define rep(i, a, n) for (int i = a; i < n; i++)
- #define per(i, a, n) for (int i = n - 1; i >= a; i--)
- #define all(v) v.begin(), v.end()
- //#define sz(v) ((int)(v).size())
- #define trav(a, x) for (auto& a: x)
- typedef long long ll;
- typedef unsigned long long ull;
- typedef vector<int> vi;
- typedef vector<ll> vll;
- //const int INF = 1e9;
- const int MOD = 1e9 + 9;
- const int di[4] = { 1, 0, -1, 0 };
- const int dj[4] = { 0, 1 ,0, -1 };
- mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
- // открытка - D, G
- // спбгу - F, G, H, I
- struct edge {
- int a, b, cap, flow; //flow - поток, который точно течет
- };
- const int MAXN = 1000, INF = 1000000007;
- int n, s, t;
- vector<int> d, ptr;
- vector<edge> e; //список ребер - главный
- vector<int> g[MAXN]; //список смежности
- void add_edge(int a, int b, int cap) { //a -> b вес cap
- edge e1 = { a, b, cap, 0 }; //прямое
- edge e2 = { b, a, 0, 0 }; //обратное (техническое)
- g[a].push_back((int)e.size()); //индекс, где в e находится ребро
- e.push_back(e1); //прямое ребро имеет четный индекс
- g[b].push_back((int)e.size());
- e.push_back(e2); //обратное ребро имеет нечетный индекс
- }
- bool bfs() {
- queue<int>q;
- q.push(s);
- d.assign(n, -1);
- d[s] = 0;
- while (q.size() > 0 && d[t] == -1) {
- int v = q.front(); q.pop();
- for (size_t i = 0; i < g[v].size(); ++i) {
- int id = g[v][i],
- to = e[id].b;
- if (d[to] == -1 && e[id].flow < e[id].cap) {
- q.push(to);
- d[to] = d[v] + 1;
- }
- }
- }
- return d[t] != -1;
- }
- int dfs(int v, int flow) {
- if (!flow) return 0;
- if (v == t) return flow;
- for (; ptr[v] < (int)g[v].size(); ++ptr[v]) {
- int id = g[v][ptr[v]],
- to = e[id].b;
- if (d[to] != d[v] + 1) continue;
- int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
- if (pushed) {
- e[id].flow += pushed;
- e[id ^ 1].flow -= pushed;
- return pushed;
- }
- }
- return 0;
- }
- ll dinic() {
- ll flow = 0; //итоговый поток
- while (true) {
- if (!bfs()) break; //строим остаточную сеть s ->t
- ptr.assign(n, 0);
- while (int pushed = dfs(s, INF)) {
- flow += pushed;
- }
- }
- return flow;
- }
- // s - исток
- // t - сток
- // n - кол-во вершин
- int main() {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- int m; cin >> n >> m;
- rep(i, 0, m) {
- int a, b, c; cin >> a >> b >> c;
- add_edge(a - 1, b - 1, c);
- }
- s = 0, t = n - 1;
- cout << dinic() << "\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement