This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub AlexanderNekrasov/Youthful-Passion-Fruit-teambook
/** * Author: Alexey Vasilyev * Date: ? * Description: Dominator tree * Time: ? */ struct DominatorTree { vector<basic_string<int>> g, rg, bucket; basic_string<int> arr, par, rev, sdom, dom, dsu, label; int n, t; DominatorTree(int n) : g(n), rg(n), bucket(n), arr(n, -1), par(n, -1), rev(n, -1), sdom(n, -1), dom(n, -1), dsu(n, 0), label(n, 0), n(n), t(0) {} void add_edge(int u, int v) { g[u] += v; } void dfs(int u) { arr[u] = t; rev[t] = u; label[t] = sdom[t] = dsu[t] = t; t++; for (int w : g[u]) { if (arr[w] == -1) { dfs(w); par[arr[w]] = arr[u]; } rg[arr[w]] += arr[u]; } } int find(int u, int x=0) { if (u == dsu[u]) return x ? -1 : u; int v = find(dsu[u], x + 1); if (v < 0) return u; if (sdom[label[dsu[u]]] < sdom[label[u]]) label[u] = label[dsu[u]]; dsu[u] = v; return x ? v : label[u]; } vector<int> run(int root) { dfs(root); iota(dom.begin(), dom.end(), 0); for (int i = t - 1; i >= 0; --i) { for (int w : rg[i]) sdom[i] = min(sdom[i], sdom[find(w)]); if (i) bucket[sdom[i]] += i; for (int w : bucket[i]) { int v = find(w); if (sdom[v] == sdom[w]) dom[w] = sdom[w]; else dom[w] = v; } if (i > 1) dsu[i] = par[i]; } for (int i = 1; i < t; i++) if (dom[i] != sdom[i]) dom[i] = dom[dom[i]]; vector<int> outside_dom(n, -1); for (int i = 1; i < t; i++) outside_dom[rev[i]] = rev[dom[i]]; //-1 if vertex is not reachable return outside_dom; } };
#line 1 "graph/DominatorTree.cpp" /** * Author: Alexey Vasilyev * Date: ? * Description: Dominator tree * Time: ? */ struct DominatorTree { vector<basic_string<int>> g, rg, bucket; basic_string<int> arr, par, rev, sdom, dom, dsu, label; int n, t; DominatorTree(int n) : g(n), rg(n), bucket(n), arr(n, -1), par(n, -1), rev(n, -1), sdom(n, -1), dom(n, -1), dsu(n, 0), label(n, 0), n(n), t(0) {} void add_edge(int u, int v) { g[u] += v; } void dfs(int u) { arr[u] = t; rev[t] = u; label[t] = sdom[t] = dsu[t] = t; t++; for (int w : g[u]) { if (arr[w] == -1) { dfs(w); par[arr[w]] = arr[u]; } rg[arr[w]] += arr[u]; } } int find(int u, int x=0) { if (u == dsu[u]) return x ? -1 : u; int v = find(dsu[u], x + 1); if (v < 0) return u; if (sdom[label[dsu[u]]] < sdom[label[u]]) label[u] = label[dsu[u]]; dsu[u] = v; return x ? v : label[u]; } vector<int> run(int root) { dfs(root); iota(dom.begin(), dom.end(), 0); for (int i = t - 1; i >= 0; --i) { for (int w : rg[i]) sdom[i] = min(sdom[i], sdom[find(w)]); if (i) bucket[sdom[i]] += i; for (int w : bucket[i]) { int v = find(w); if (sdom[v] == sdom[w]) dom[w] = sdom[w]; else dom[w] = v; } if (i > 1) dsu[i] = par[i]; } for (int i = 1; i < t; i++) if (dom[i] != sdom[i]) dom[i] = dom[dom[i]]; vector<int> outside_dom(n, -1); for (int i = 1; i < t; i++) outside_dom[rev[i]] = rev[dom[i]]; //-1 if vertex is not reachable return outside_dom; } };