diff --git a/graph/hld.cc b/graph/hld.cc new file mode 100644 index 0000000..28e4bed --- /dev/null +++ b/graph/hld.cc @@ -0,0 +1,43 @@ +namespace HLD { + struct node_info { + int father, depth, hson, size, head, dfn = -1; + }; + + // returns: (dfs sequence, node info) + // node numbering starts from `1` + // if `dfn(v) == -1`, then node `v` is never accessed. + pair, vector> work(int n, const vector>& ch, int root = 0) { + vector seq; + vector res(n + 1); + auto dfs1 = [&] (auto dfs1, int v, int pa) -> void { + res[v].father = pa; + res[v].depth = res[pa].depth + 1; + res[v].size = 1; + int mx = 0; + for (auto&& u : ch[v]) { + if (u == pa) continue; + dfs1(dfs1, u, v); + res[v].size += res[u].size; + if (res[u].size > mx) { + mx = res[u].size; + res[v].hson = u; + } + } + }; + dfs1(dfs1, root, root); + int tm = 0; + auto dfs2 = [&] (auto dfs2, int v, int head) -> void { + res[v].dfn = tm++; + seq.emplace_back(v); + res[v].head = head; + if (not res[v].hson) return; + dfs2(dfs2, res[v].hson, head); + for (auto&& u : ch[v]) { + if (u == res[v].father or u == res[v].hson) continue; + dfs2(dfs2, u, u); + } + }; + dfs2(dfs2, root, root); + return { seq, res }; + } +}