From a7543847a9f12df6470734d341cae79ea10dc596 Mon Sep 17 00:00:00 2001 From: Bruno Freitas Tissei <bft15@inf.ufpr.br> Date: Sat, 3 Feb 2018 11:26:22 -0200 Subject: [PATCH] Add LCA Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br> --- graph/lca.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 graph/lca.cpp diff --git a/graph/lca.cpp b/graph/lca.cpp new file mode 100644 index 0000000..f441761 --- /dev/null +++ b/graph/lca.cpp @@ -0,0 +1,78 @@ +/** + * Lowest Common Ancestor - LCA + * + * Complexity (Time): + * preprocess -> O(n log n) + * query -> O(log n) + * Complexity (Space): O(n + m + n log n) + * + * + * OBS: * = return sum path to LCA + * ** = return max value on path to LCA + */ + +vector<ii> graph[MAX]; + +int h[MAX]; +int par[MAX][MAXLOG], cost[MAX][MAXLOG]; + +// Perform DFS while filling h, par, and cost +void dfs(int v, int p = -1, int c = 0) { + par[v][0] = p; + //*** cost[v][0] = c; + + if (p + 1) + h[v] = h[p] + 1; + + for (int i = 1; i < MAXLOG; i++) + if (par[v][i - 1] + 1) { + par[v][i] = par[par[v][i - 1]][i - 1]; + //*** cost[v][i] += cost[v][i - 1] + cost[par[v][i - 1]][i - 1]; + } + + for (auto u : graph[v]) + if (p != u.fi) + dfs(u.fi, v, u.se); +} + +// Preprocess tree with rooted at v +void preprocess(int v) { + memset(par, -1, sizeof par); + memset(cost, 0, sizeof cost); + dfs(v); +} + +// Return LCA between p and q +int query(int p, int q) { + //*** int ans = 0; + + if (h[p] < h[q]) + swap(p, q); + + for (int i = MAXLOG - 1; i >= 0; i--) + if (par[p][i] + 1 && h[par[p][i]] >= h[q]) { + //* ans += cost[p][i]; + //** ans = max(ans, cost[p][i]); + p = par[p][i]; + } + + if (p == q) + return p; + //*** return ans; + + for (int i = MAXLOG - 1; i >= 0; i--) + if (par[p][i] + 1 && par[p][i] != par[q][i]) { + //* ans += cost[p][i] + cost[q][i]; + //** ans = max(ans, max(cost[p][i], cost[q][i])); + p = par[p][i]; + q = par[q][i]; + } + + return dp[p][0]; + + //* if (p == q) return ans; + //* else return ans + cost[p][0] + cost[q][0]; + + //** if (p == q) return ans; + //** else return max(ans, max(cost[p][0], cost[q][0])); +} -- GitLab