summaryrefslogtreecommitdiff
path: root/graph/hld.cpp
diff options
context:
space:
mode:
authormzuenni <michi.zuendorf@gmail.com>2022-06-27 17:19:28 +0200
committermzuenni <michi.zuendorf@gmail.com>2022-06-27 17:19:28 +0200
commit5ab8a5088b729a9953b8dff1b2a985dc8fb2098b (patch)
treeed40d6936c0e9eee40ba62751cbf99ecddbaddc2 /graph/hld.cpp
parentadabbad9c51cf7cd3874bfde8eac1fbcf84fec10 (diff)
updated tcr
Diffstat (limited to 'graph/hld.cpp')
-rw-r--r--graph/hld.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/graph/hld.cpp b/graph/hld.cpp
new file mode 100644
index 0000000..3d63903
--- /dev/null
+++ b/graph/hld.cpp
@@ -0,0 +1,52 @@
+vector<vector<int>> adj;
+vector<int> sz, in, out, nxt, par;
+int t;
+
+void dfs_sz(int v = 0, int from = -1) {
+ sz[v] = 1;
+ for (auto& u : adj[v]) {
+ if (u != from) {
+ dfs_sz(u, v);
+ sz[v] += sz[u];
+ }
+ if (adj[v][0] == from || sz[u] > sz[adj[v][0]]) {
+ swap(u, adj[v][0]);
+}}}
+
+void dfs_hld(int v = 0, int from = -1) {
+ par[v] = from;
+ in[v] = t++;
+ for (int u : adj[v]) {
+ if (u == from) continue;
+ nxt[u] = (u == adj[v][0] ? nxt[v] : u);
+ dfs_hld(u, v);
+ }
+ out[v] = t;
+}
+
+void init() {
+ int n = sz(adj);
+ sz.assign(n, 0); in.assign(n, 0); out.assign(n, 0);
+ nxt.assign(n, 0); par.assign(n, -1);
+ t = 0;
+ dfs_sz(); dfs_hld();
+}
+
+vector<pair<int, int>> get_intervals(int u, int v) {
+ vector<pair<int, int>> res;
+ while (true) {
+ if (in[v] < in[u]) swap(u, v);
+ if (in[nxt[v]] <= in[u]) {
+ res.eb(in[u], in[v] + 1);
+ return res;
+ }
+ res.eb(in[nxt[v]], in[v] + 1);
+ v = par[nxt[v]];
+}}
+
+int get_lca(int u, int v) {
+ while (true) {
+ if (in[v] < in[u]) swap(u, v);
+ if (in[nxt[v]] <= in[u]) return in[u];
+ v = par[nxt[v]];
+}}