Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- #define long ll
- #define all(x) begin(x), end(x)
- namespace flow {
- const int N = 512, INF = 0x3f3f3f3f;
- int SOURCE = N - 1, SINK = N - 2;
- struct Edge {
- int u = 0, r = 0, c = 0, f = 0;
- Edge(int aa, int bb, int cc, int dd) : u(aa), r(bb), c(cc), f(dd) {}
- };
- vector<Edge> g[N];
- void add(int a, int b, int c) {
- g[a].emplace_back(b, (int)g[b].size(), c, 0);
- g[b].emplace_back(a, (int)g[a].size() - 1, 0, 0);
- }
- int lim, dist[N], p[N];
- bool bfs() {
- memset(dist, 0x3f, sizeof dist);
- memset(p, 0x00, sizeof p);
- queue<int> q;
- q.push(SOURCE);
- dist[SOURCE] = 0;
- while (q.size()) {
- int v = q.front();
- q.pop();
- for (auto &e : g[v]) {
- if (dist[e.u] > dist[v] + 1 && e.c - e.f >= lim) {
- q.push(e.u);
- dist[e.u] = dist[v] + 1;
- }
- }
- }
- return dist[SINK] < INF;
- }
- int dfs(int v, int min_c) {
- if (v == SINK) {
- return min_c;
- }
- for (; p[v] < (int)g[v].size(); ++p[v]) {
- auto &e = g[v][p[v]];
- if (dist[e.u] > dist[v] && e.c - e.f >= lim) {
- int d = dfs(e.u, min(min_c, e.c - e.f));
- if (d > 0) {
- e.f += d;
- g[e.u][e.r].f -= d;
- return d;
- }
- }
- }
- return 0;
- }
- long find_flow() {
- long answer = 0;
- lim = 1;
- for (lim = 1 << 30; lim > 0; lim /= 2) {
- while (bfs()) {
- int d = dfs(SOURCE, INF);
- while (d > 0) {
- answer += d;
- d = dfs(SOURCE, INF);
- }
- }
- }
- return answer;
- }
- }
- int n, m;
- int main() {
- #ifdef LC
- //assert(freopen("input.txt", "r", stdin));
- #endif
- ios::sync_with_stdio(false);
- cin.tie(nullptr);
- cin >> n >> m;
- for (int a, b, c, i = 0; i < m; ++i) {
- cin >> a >> b >> c;
- --a;
- --b;
- flow::add(a, b, c);
- }
- flow::SOURCE = 0;
- flow::SINK = n - 1;
- cout << flow::find_flow() << '\n';
- return 0;
- }
- /*****
- Cool test:
- 4 5
- 1 2 2
- 1 3 1
- 2 3 1
- 2 4 1
- 3 4 2
- *****/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement