LCA模板
时间: 2025-05-05 17:30:45 浏览: 21
### LCA(最近公共祖先)问题的模板代码与算法实现
对于解决LCA问题,倍增法是一种高效的方法。该方法通过预处理节点之间的关系来加速查询过程。
#### 倍增法求解LCA的核心思想
核心在于预先计算每个节点向上跳转$2^k$步后的父节点位置,并记录这些跳跃路径上的最值或和等信息以便后续快速查询[^1]。
#### 预处理阶段
在预处理过程中,构建稀疏表用于存储从任意一点出发经过若干次二进制幂次数目的上移操作所能到达的位置以及对应的最大最小边权或其他属性值。
```cpp
const int MAXN = 5e4 + 5;
int dep[MAXN], fa[MAXN][20]; //dep[i]表示i结点到根的距离,fa[i][j]表示i结点往上第2^j个祖先是谁
vector<int> G[MAXN];
void dfs(int u,int father){
fa[u][0]=father;
for(auto v : G[u]){
if(v==father) continue;
dep[v]=dep[u]+1;
dfs(v,u);
}
}
//初始化f数组
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i<=n;i++)
if(fa[i][j-1]!=-1)
fa[i][j]=fa[fa[i][j-1]][j-1];
```
#### 查询阶段
当需要找到两个给定节点u,v之间距离最近的那个共同祖先时,则可以通过比较两者深度并调整至相同层次再逐步回溯直至相遇于某一层级完成定位工作。
```cpp
int lca(int u,int v){
if(dep[u]<dep[v]) swap(u,v); //保证u更深或者一样深
for(int i=18;i>=0;i--) //先让较深的一个回到跟另一个同一层
if((dep[u]-dep[v])&(1<<i))
u=fa[u][i];
if(u==v) return u; //此时在同一层了 如果相等就返回
for(int i=18;i>=0;i--)
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];
v=fa[v][i];
} //一起往上面走直到第一次不一致的地方停下
return fa[u][0]; //最后一步走到lca处
}
```
上述C++代码实现了基于DFS遍历树结构来进行倍增法预处理,并提供了`lca()`函数用来在线询问两节点间最低公共祖先的具体编号。
阅读全文
相关推荐

















