14-树

290 字
1 分钟
14-树

#

LCA#

用预处理的二进制划分的步长为2i2^i的父亲数组作为数据结构进行加速

#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];
}
};

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

14-树
https://skaco2.com/posts/01-algorithm/14-树/
作者
SKACO2
发布于
2026-04-09
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
SKACO2
Hello……
公告
欢迎来到我的博客!
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
53
分类
8
标签
54
总字数
58,255
运行时长
0
最后活动
0 天前

目录