lca学习笔记

首先lca是树上两个节点的最近公共祖先,也就是两个节点的公共祖先中最深的那个。(祖先的定义都知道吧)
最简单的是倍增算法。

倍增

朴素算法是一层层往上跳,而倍增是每次跳\(2^i\)次,大大减少了跳跃次数。

预处理

我们需要两个数组:第\(2^j\)个祖先和它的深度。

实现

首先让两个节点深度相同(往上跳),然后一起往上跳直到两点第一次重合,这就是最近公共祖先。

点击查看代码
void dfs(int i , int fn){
	fa[i][0] = fn , deep[i] = deep[fn] + 1;
	for(int j=1;j<31;j++){
		fa[i][j] = fa[fa[i][j-1]][j-1];
	}
	for(int j=0;j<vec[i].size();j++){
		if(vec[i][j]==fn)continue;
		dfs(vec[i][j],i);
	}
}
int lca(int x , int y){
	if(deep[x]>deep[y])swap(x,y);
	int tmp = deep[y] - deep[x];
	for(int j=0;tmp;j++,tmp>>=1){
		if(tmp&1)y = fa[y][j];
	}
	if(y==x)return x;
	int j;
	for(j=30;j>=0&&y!=x;j--) {
		if(fa[x][j]!=fa[y][j]){
			x = fa[x][j] , y = fa[y][j];
		}
	}
	return fa[x][0];
}
posted @ 2025-09-27 21:51  虚空远行者  阅读(18)  评论(0)    收藏  举报