[Tarjan]LCA算法

本文介绍了Tarjan算法在求解有根树中两点的最低公共祖先(LCA)问题上的应用。首先阐述了祖先和LCA的基本概念,然后详细讲解了Tarjan算法的前序部分及其神奇之处,并通过实例解析了算法的运行过程,展示如何通过后序遍历来高效求解LCA问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先来一波理论

祖先

u的祖先集合是suu的父亲为fu树根为root
那么

su={{u,sfu}uurootu=root

通俗点讲:su就是uu的父亲和u的父亲的父亲和u的父亲的父亲的父亲
LCA

设一颗有根树上的两点u,v,它们的LCAlu,v
那么lu,vsusv并且slu,vsusv
也就是它们的公共祖先中深度最小的点

来一波tarjan

前叙

tarjan是一个神奇的算法,它的复杂度是O(n+q),加上vector的大常数,妥妥的TLE,好吧,别学我。

神奇的tarjan的神奇的算法

先奶一波代码

void LCA(int s)
{
    ved[s]=1;//如果把连向父亲节点的边删掉,就不用这一步
    fr(i,0,t[s].size()-1)
        if(!ved[t[s][i]])
        {
            LCA(t[s][i]);
            f[t[s][i]]=s;
        }
    fr(i,0,as[s].size()-1)
        if(vis[as[s][i]])
            ans[nu[s][i]]=getf(as[s][i]);
    vis[s]=1;                
}

tarjan就是后序遍历发现没
举个栗子
栗子*1
我们要求:

1 3
3 4
2 5
4 5

我们先沿着123欢快得走下去,
然后无路可走了QAQ,接着就留下个标记,XXX到3一游,并给3了一个flag:从2来的

然后又回到了2,接着走到了4,无路可走,返回。

等等。。。3之前也走过,所以,找到3立的flag2,于是l3,4=2就得到了

然后继续走,给2立了1flag

然后到了5,发现了一件大事:24都走过了,然后找到了它们的flag12

l4,5=2不对劲啊。对哦,要一直沿着flag往上浪,于是就421l4,5=1

然后回了1,没地方放flag了,那就跳过吧。
然后发现:3走过照常,直接沿着flag走,得l1,3=1
所以答案为:

1
2
1
1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值