//网络流 intbfs(int S, int T){ memset(dep, 0, sizeof(dep)); memcpy(cur, head, sizeof(head)); q[h = t = 1] = S; dep[S] = 1; while (h <= t) { int u = q[h++]; for (int i = head[u]; i; i = nxt[i]) { int v = to[i]; if (!dep[v] && c[i]) { dep[v] = dep[u] + 1; q[++t] = v; } } } return dep[T]; }
intdfs(int u, int T, int lim){ if (u == T || !lim) return lim; int flow = 0, k; for (int i = cur[u]; i && lim; i = nxt[i]) { cur[u] = i; int v = to[i]; if (dep[v] == dep[u] + 1 && c[i]) { k = dfs(v, T, min(lim, c[i])); if (!k) dep[v] = 0; lim -= k, flow += k; c[i] -= k, c[i ^ 1] += k; } } return flow; }
intdinic(int S, int T){ for (int i = 2; i <= e_tot; ++i) { c[i] = c[i] + c[i ^ 1]; c[i ^ 1] = 0; } int res = 0; while (bfs(S, T)) res += dfs(S, T, inf); return res; }
//构造最小割树 voidsolve(int l, int r){ if (l == r) return ; int S = node[l], T = node[l + 1]; int cut = dinic(S, T); link(S, T, cut); link(T, S, cut); int tot1 = 0, tot2 = 0; for (int i = l; i <= r; ++i) { if (dep[node[i]]) tmp1[++tot1] = node[i]; else tmp2[++tot2] = node[i]; } for (int i = 1; i <= tot1; ++i) node[l - 1 + i] = tmp1[i]; for (int i = 1; i <= tot2; ++i) node[l + tot1 - 1 + i] = tmp2[i]; solve(l, l + tot1 - 1); solve(l + tot1, r); }
voiddfs(int u, int _fa){ dep[u] = dep[_fa] + 1; for (auto it : path[u]) { int v = it.first, len = it.second; if (v == _fa) continue; minn[v][0] = len, fa[v][0] = u; dfs(v, u); } }
// 查询任意两点的最小割 intquery(int x, int y){ int res = 0x3f3f3f3f; if (dep[x] < dep[y]) swap(x, y); for (int i = 10; ~i; --i) { if (dep[fa[x][i]] >= dep[y]) { res = min(res, minn[x][i]); x = fa[x][i]; } } if (x == y) return res; for (int i = 10; ~i; --i) { if (fa[x][i] != fa[y][i]) { res = min(res, minn[x][i]); res = min(res, minn[y][i]); x = fa[x][i]; y = fa[y][i]; } } res = min(res, minn[x][0]); res = min(res, minn[y][0]); return res; }