loj #127. 最大流 加强版
// luogu-judger-enable-o2
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010, M = 250010;
const unsigned long long INF = (1 << 31) - 1;
int n, m, S, T;
int h[N], e[M], f[M], ne[M], idx;
int q[N], d[N], nh[N];
inline void add(int a, int b, int c) { e[idx] = b, f[idx] = c, ne[idx] = h[a], h[a] = idx++; }
bool bfs() {
memset(d, -1, sizeof d);
q[0] = S, d[S] = 0, nh[S] = h[S];
int hh = 0, tt = 1;
int flag = 0;
while (hh < tt) {
int t = q[hh++];
for (int i = h[t]; ~i; i = ne[i]) {
int v = e[i];
if (d[v] == -1 && f[i]) {
d[v] = d[t] + 1;
nh[v] = h[v]; // 可以在开头全copy
if (v == T)
flag = 1; // return true;
q[tt++] = v;
}
}
}
return flag;
}
int find(int u, int limit) {
if (u == T)
return limit;
int flow = 0;
for (int i = nh[u]; ~i && flow < limit; i = ne[i]) { // 1. nh 优化, 2. 增广最大量优化
nh[u] = i; // nh当前可行弧优化
int v = e[i];
if (d[v] == d[u] + 1 && f[i]) {
int t = find(v, min(f[i], limit - flow));
if (t)
flow += t, f[i] -= t; //, f[i ^ 1] += t;
else
d[v] = -1; // 3. 废点优化
}
}
return flow;
}
int dinic() {
int res = 0, flow;
while (bfs())
while (flow = find(S, INF)) res += flow;
return res;
}
int main() {
scanf("%d%d%d%d", &n, &m, &S, &T);
memset(h, -1, sizeof h);
while (m--) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c), add(b, a, 0);
}
printf("%d\n", dinic());
return 0;
}