structGraph { structEdge { int v, nt; ll c; // 可通过流量 } e[M << 1]; int hd[N], tot = 1; // 注意从 2 开始对边编号 voidadd(int u, int v, ll c){ e[++tot] = {v, hd[u], c}, hd[u] = tot; } voiduadd(int u, int v, ll c){ add(u, v, c), add(v, u, 0); } } g;
namespace EK { int S, T; // 源点,汇点 int prep[N], pree[N]; // 前驱点,前驱边 ll l[N]; ll flow(){ ll res = 0; while (true) { queue<int> q; vector<int> ph; q.push(S); l[S] = LLINF; while (!q.empty()) { int u = q.front(); q.pop(), ph.push_back(u); for (int i = g.hd[u]; i; i = g.e[i].nt) { int v = g.e[i].v; if (!l[v] && g.e[i].c) { prep[v] = u, pree[v] = i; l[v] = min(l[u], g.e[i].c); q.push(v); } } if (l[T]) break; } if (!l[T]) break;
for (int u : ph) l[u] = 0; // 重置边的流量
for (int u = T; u != S; u = prep[u]) { int i = pree[u]; g.e[i].c -= l[T], g.e[i ^ 1].c += l[T]; } res += l[T]; } return res; } } // namespace EK
int n, m;
intmain(){ cin >> n >> m >> EK::S >> EK::T;
for (int i = 1, u, v, c; i <= m; i++) { cin >> u >> v >> c; g.uadd(u, v, c); }