From 47fcbd601116f318a89a432d985d4ecf0cebff41 Mon Sep 17 00:00:00 2001 From: subcrip Date: Thu, 5 Sep 2024 23:27:47 +0800 Subject: [PATCH] Add graph/virtual_tree.cc --- graph/virtual_tree.cc | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 graph/virtual_tree.cc diff --git a/graph/virtual_tree.cc b/graph/virtual_tree.cc new file mode 100644 index 0000000..361a619 --- /dev/null +++ b/graph/virtual_tree.cc @@ -0,0 +1,53 @@ +// BUG: unchecked code +struct virtual_tree { + int n, root; + vector> e; + LCA lca; + vector dfn; + vector ps; + virtual_tree(const vector>& e, int root) : n(e.size() - 1), root(root), e(e), lca(vector> {{}, {}}), dfn(n + 1), ps(n + 1) { + vector> ch(n + 1); + for (int u = 0; u <= n; ++u) { + for (auto&& [v, w] : e[u]) { + ch[u].emplace_back(v); + } + } + lca = LCA(ch); + int t = 0; + auto dfs = [&] (auto dfs, int v, int pa) -> void { + dfn[v] = ++t; + for (auto&& [u, w] : e[v]) { + if (u == pa) continue; + ps[u] = ps[v] + w; + dfs(dfs, u, v); + } + }; + dfs(dfs, root, 0); + } + // returned vertex number starts from 0 + vector> generate(vector pivots) { + int m = pivots.size(); + if (m == 0) return {}; + sort_by_key(pivots.begin(), pivots.end(), expr(dfn[v], int v)); + vector a; + for (int i = 0; i < m - 1; ++i) { + int v = pivots[i]; + int u = lca.query(pivots[i], pivots[i + 1]); + a.emplace_back(v); + a.emplace_back(u); + } + a.emplace_back(pivots[m - 1]); + sort_by_key(a.begin(), a.end(), expr(dfn[v], int v)); + m = unique(a.begin(), a.end()) - a.begin(); + unordered_map mp; + for (int i = 0; i < m; ++i) { + mp[a[i]] = i; + } + vector> ret(m); + for (int i = 0; i < m - 1; ++i) { + int l = lca.query(a[i], a[i + 1]); + edgew(ret, mp[l], i + 1, ps[a[i + 1]] - ps[l]); + } + return ret; + } +};