本文介绍的是LCA算法中的tarjan离线算法。
不知道LCA定义?请戳这儿
核心思想
- 并查集
pre[u]表示u点的父亲
pre[pre[pre[…u…]]]可以求u的某一层父亲结点
- 原理
tanjan离线算法的实现并不好叙述,需要深刻理解DFS的过程。给定一棵树,如下:
如果我们想求K与F的最近公共祖先,我们先把K和F连接,K指向F,F同样指向K。在DFS过程中,
首先从根节点A开始遍历,然后假设遍历到B,再从B开始遍历,到E,到K,然后返回,用一个数组
记录K点已经完全遍历,并在回溯的过程中建立并查集,即:
vis[K]=1
pre[K]=E
再返回
vis[E]=1
pre[E]=B
然后遍历的F,发现F的连接点K已经完全遍历,则寻找K此时的父节点,找到B点,则B为K、E的LCA。
总结
将所有想要寻找的点对连接起来,若某一点的连接点已经完全遍历,对其连接点找此时树的根,
由于树(并查集)是在DFS回溯过程中建立的,此时这个小树的根即为这两点的LCA。时间复杂度:O(n+q)
附加代码
定义及初始化
|
|
算法函数
|
|