LCA的离线算法Tarjan.
总的来说是深度遍历。以根为节点建立并查集。比如说求p,v的lca。当访问到p的时候检查v是否已经访问过。如果访问过,那么他们的lca就是v现在所在的并查集里面的元素。如果没有访问到。那么等到v访问到的时候可以操作一下。
充分利用了递归这个操作,所以不必要保存以前的东西,自然而然的就将u里面的所有的子节点子孙节点都和并到一块去了。
这个想了比较长的时间。
这个是伪代码
LCA(u) {
Make-Set(u) ancestor[Find-Set(u)]=u 对于u的每一个孩子v { LCA(v) Union(u) ancestor[Find-Set(u)]=u } checked[u]=true 对于每个(u,v)属于P { if checked[v]=true then 回答u和v的最近公共祖先为 ancestor[Find-Set(v)] }}
方法二:
对于一个二叉树来说,可以先进行一遍广度搜索,记录自己节点的。这样的话到时候就变成了两个链表相交的情况。比较容易实现了。
在配合用动态规划。用一个数组来存储,这样的话就更好了。