Pixiv - Miracle
14-树
290 字
1 分钟
14-树
树
LCA
用预处理的二进制划分的步长为的父亲数组作为数据结构进行加速
#include <bits/stdc++.h>
using namespace std;using ll = long long;using pii = pair<int, int>;
class lca { vector<int> depth; vector<ll> dis; vector<vector<int>> pa;// 本质为步长为2^i的父亲数组
public: lca(const vector<vector<int>>& edges) { int n = edges.size() + 1; int m = bit_width((unsigned) n); vector<vector<pii>> g(n); depth.resize(n); dis.resize(n); pa.resize(n, vector<int>(m, -1));
for (auto& e : edges) { int x = e[0], y = e[1], w = e[2]; g[x].emplace_back(y, w); g[y].emplace_back(x, w); }
auto dfs = [&](auto&& dfs, int x, int fa) -> void { pa[x][0] = fa; for (auto& [y, w] : g[x]) { if (y != fa) { depth[y] = depth[x] + 1; dis[y] = dis[x] + w; pa[y][0] = x; dfs(dfs, y, x); } } }; dfs(dfs, 0, -1);
for (int i = 0; i < m - 1; ++i) { for (int x = 0; x < n; ++x) { int p = pa[x][i]; if (p != -1) { pa[x][i + 1] = pa[p][i]; } } } }
int get_kth_anc(int node, int k) { for (; k > 0 && node >= 0; k &= k - 1) { node = pa[node][countr_zero((unsigned) k)]; } return node; }
int get_lca(int x, int y) { if (depth[x] > depth[y]) swap(x, y);
y = get_kth_anc(y, depth[y] - depth[x]); if (y == x) return x;
for (int i = pa.size() - 1; i >= 0; --i) { int px = pa[x][i], py = pa[y][i]; if (px != py) { x = px; y = py; } } return pa[x][0]; }};文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
随机文章 随机推荐