1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| vector<int> G[maxn], rG[maxn]; vector<int> dt[maxn];
namespace DomTree { int fa[maxn], idx[maxn], tot, ridx[maxn]; int c[maxn], best[maxn], semi[maxn], idom[maxn]; void clear(int n) { tot = 0; fill(c, c + n + 1, -1); fill(idx, idx + n + 1, 0); for (int i = 0; i <= n; i++) { dt[i].clear(); semi[i] = best[i] = i; } } void dfs(int u) { idx[u] = ++tot; ridx[tot] = u; for (int& v: G[u]) { if (idx[v]) continue; fa[v] = u; dfs(v); } } int fix(int x) { if (c[x] == -1) return x; int &f = c[x], rt = fix(f); if (idx[semi[best[x]]] > idx[semi[best[f]]]) best[x] = best[f]; return f = rt; } void build(int rt) { dfs(rt); for (int i = tot; i >= 1; i--) { int x = ridx[i], mn = tot + 1; for (int& u: rG[x]) { if (!idx[u]) continue; fix(u); mn = min(mn, idx[semi[best[u]]]); } c[x] = fa[x]; dt[semi[x] = ridx[mn]].push_back(x); x = ridx[i - 1]; for (int& u: dt[x]) { fix(u); if (semi[best[u]] != x) idom[u] = best[u]; else idom[u] = x; } dt[x].clear(); } for (int i = 2; i <= tot; i++) { int u = ridx[i]; if (idom[u] != semi[u]) idom[u] = idom[idom[u]]; dt[idom[u]].push_back(u); } } }
|