This documentation is automatically generated by online-judge-tools/verification-helper
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A"
#include <bits/stdc++.h>
using namespace std;
#include "../MaxFlow/MaxFlowDinic.h"
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int n, m; cin >> n >> m;
MaxFlow flow(n);
while (m--) {
int u, v, c; cin >> u >> v >> c;
flow.addEdge(u, v, c);
}
cout << flow.getMaxFlow(0, n-1) << endl;
}
#line 1 "Graph/tests/aizu_grl_6_a_maxflow_dinic.test.cpp"
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A"
#include <bits/stdc++.h>
using namespace std;
#line 1 "Graph/MaxFlow/MaxFlowDinic.h"
// Source: e-maxx.ru
// Tested with: VOJ - NKFLOW, VOJ - MCQUERY (Gomory Hu)
// Usage:
// MaxFlow flow(n)
// For each edge: flow.addEdge(u, v, c)
// Index from 0
// Tested:
// - https://open.kattis.com/problems/maxflow
// - https://www.lydsy.com/JudgeOnline/problem.php?id=1001
// - TLE on https://oj.vnoi.info/problem/fflow
const int INF = 1000000000;
struct Edge {
int a, b, cap, flow;
};
struct MaxFlow {
int n, s, t;
vector<int> d, ptr, q;
vector< Edge > e;
vector< vector<int> > g;
MaxFlow(int _n) : n(_n), d(_n), ptr(_n), q(_n), g(_n) {
e.clear();
for (int i = 0; i < n; i++) {
g[i].clear();
ptr[i] = 0;
}
}
void addEdge(int a, int b, int cap) {
Edge e1 = { a, b, cap, 0 };
Edge e2 = { b, a, 0, 0 };
g[a].push_back( (int) e.size() );
e.push_back(e1);
g[b].push_back( (int) e.size() );
e.push_back(e2);
}
int getMaxFlow(int _s, int _t) {
s = _s; t = _t;
int flow = 0;
for (;;) {
if (!bfs()) break;
std::fill(ptr.begin(), ptr.end(), 0);
while (int pushed = dfs(s, INF))
flow += pushed;
}
return flow;
}
private:
bool bfs() {
int qh = 0, qt = 0;
q[qt++] = s;
std::fill(d.begin(), d.end(), -1);
d[s] = 0;
while (qh < qt && d[t] == -1) {
int v = q[qh++];
for (int i = 0; i < (int) g[v].size(); i++) {
int id = g[v][i], to = e[id].b;
if (d[to] == -1 && e[id].flow < e[id].cap) {
q[qt++] = 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;
}
};
#line 7 "Graph/tests/aizu_grl_6_a_maxflow_dinic.test.cpp"
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int n, m; cin >> n >> m;
MaxFlow flow(n);
while (m--) {
int u, v, c; cin >> u >> v >> c;
flow.addEdge(u, v, c);
}
cout << flow.getMaxFlow(0, n-1) << endl;
}