LCA模板

本文解析了LCA(Least Common Ancestors)算法,介绍了利用倍增思想在有根树中找到任意两点的最近公共祖先的方法,包括预处理深度信息、核心语句和dfs遍历,以及关键代码实现。通过实例演示了如何在给定的树状结构中快速定位最近公共祖先节点。
摘要由CSDN通过智能技术生成

题目链接
LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的 公共祖先 。 ———来自百度百科
学习视频:LCA算法讲解

利用倍增的思想从大往小跳,从小往大跳可能会有误判,跳2的整数次幂。
fa[i][j]表示i的2^j的祖先;

预处理:
把每一层的高度存在deap[i]中
核心语句fa[now][i]=fa[fa[now][i-1]][i-1];
now的2i的祖先==2i-1的2i-1的祖先

void dfs(int now, int fath) {
	fa[now][0] = fath;
	deap[now] = deap[fath]+1;
	for(int i=1; i<=lg[deap[now]]; i++) {
		fa[now][i]=fa[fa[now][i-1]][i-1];
	}
	for(int i=head[now]; i; i=e[i].to)
		if(e[i].from != fath)
			dfs(e[i].from,now);
}

倍增LCA

代码:
x=fa[x][lg[deap[x]-deap[y]]-1];
先跳到同一深度
然后一起往上跳,跳到LCA的下面

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5+100;
struct node {
	int from,to;
} e[maxn<<1];
int head[maxn],tot=1;
int deap[maxn],fa[maxn][22],lg[maxn];
//fa[i][j]存的[i]向上走2的j次方的祖先;
void add(int x,int y) {
	e[tot].from = y;
	e[tot].to = head[x];
	head[x] = tot++;
}
void dfs(int now, int father) {
	fa[now][0] = father;
	deap[now] = deap[father]+1;
	for(int i=1; i<=lg[deap[now]]; i++) {
		fa[now][i]=fa[fa[now][i-1]][i-1];
	}
	for(int i=head[now]; i; i=e[i].to)
		if(e[i].from != father)
			dfs(e[i].from,now);
}
int LCA(int x,int y) {
	if(deap[x]<deap[y])
		swap(x,y);
	while(deap[x]>deap[y])
		x=fa[x][lg[deap[x]-deap[y]]-1];
	if(x==y) {
		return x;
	}
	for(int k=lg[deap[x]]-1; k>=0; k--) {
		if(fa[x][k] != fa[y][k]) {
			x=fa[x][k],y=fa[y][k];
		}
	}
	return fa[x][0];
}
int main() {
	int n,m,s;
	cin>>n>>m>>s;
	for(int i=1; i<=n-1; i++) {
		int x,y;
		cin>>x>>y;
		add(x,y);//无向图
		add(y,x);
	}
	for(int i=1; i<=n; i++) {
		lg[i] = lg[i-1]+(1<<lg[i-1]==i);
	}
	dfs(s,0);
	for(int i=1; i<=m; i++) {
		int x,y;
		cin>>x>>y;
		cout<<LCA(x,y)<<endl;
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值