ISAP
struct Edge { int lst; int v; int w; }; const int maxn = 1e5+500; const int maxe = (1e5+500) * 2; const int inf = 0x3f3f3f3f; class ISAP { public : Edge edge[maxe]; int head[maxn], qsz; int d[maxn], cur[maxn], num[maxn]; int st, ed, n; void add(int u, int v, int w) { edge[qsz] = (Edge){head[u], v, w}; head[u] = qsz++; edge[qsz] = (Edge){head[v], u, w}; head[v] = qsz++; } void bfs(int t) { queue<int> q; memset(num, 0, sizeof(num)); memset(d, 0, sizeof(d)); for (int i=1; i<=n; ++i) cur[i] = head[i]; d[t] = 1; num[d[t]]++; q.push(t); while (!q.empty()) { int u = q.front(); q.pop(); for (int i=head[u]; ~i; i=edge[i].lst) { int v = edge[i].v; if (!d[v]) { d[v] = d[u] + 1; num[d[v]]++; q.push(v); } } } } int dfs(int u, int limit) { if (u==ed) return limit; int flow = 0, v; for (int i=cur[u]; ~i; i=cur[u]=edge[i].lst) { v = edge[i].v; if (d[u] == d[v] + 1) { int f = dfs(v, min(limit, edge[i].w)); flow += f; limit -= f; edge[i].w -= f; edge[i^1].w += f; if (!limit) return flow; } } if (!(--num[d[u]])) d[st] = n + 1; d[u] += 1; ++num[d[u]]; cur[u] = head[u]; return flow; } void init(int n) { this->n = n; qsz = 0; memset(head, -1, sizeof head); } int maxflow(int st, int ed) { bfs(ed); this->st = st; this->ed = ed; int res = 0; do { res += dfs(st, inf); } while (d[st] <= n); return res; } }isap;