最近公共祖先LCA

最近公共祖先LCA

若两个节点的祖先相同,则叫该节点的公共祖先
简称LCA
显然,两个节点的LCA只有一个,且一定是两个点到根的路径中重复部分最下端的点
算法1(暴力法):

  • 求出每一个结点的深度

  • 询问两个节点是否重合,若重合,则LCA已求出

  • 否则,选择两个点中深度较大的点,并移动到他的父亲

  • 重复执行2,3步
    在这里插入图片描述
    上图的执行流程如下:

    • 两个指针位于3与9。
    • 此时9节点深度较大,向上移动到它的父亲7
    • 此时两个节点深度一样,移动3到他的父亲1
    • 此时7深度较大,向上移动到5号节点
    • 此时两个节点深度一样,移动1到0
    • 此时5深度较大,向上移动到0,两个指针重合,0为LCA.
      算法代码如下
int de[MAXN],fa[MAXN];
void dfs(int x,int fath)//遍历这棵树并求出每个点的深度和父亲
{
	fa[x]=fath;de[x]=de[fath]+1;
	for(int i=fi[x];i;i=ne[i])
		if(to[i]!=fath)dfs(to[i],x);
}
int getlca(int x,int y)//求LCA
{
	while(x!=y)
	{
		//将节点深度较大的点的指针往上移动
		if(de[x]>=de[y])
			x=fa[x];
		else
			y=fa[y];
	}
	return x;
}
暴力法
时间复杂度O(nq)
优点容易理解和实现,存储空间小,支持动态的树
缺点最坏情况下时间复杂度很高
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值