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)]
}

  }

  方法二:

  对于一个二叉树来说,可以先进行一遍广度搜索,记录自己节点的。这样的话到时候就变成了两个链表相交的情况。比较容易实现了。

  在配合用动态规划。用一个数组来存储,这样的话就更好了。

posted @ 2011-06-02 16:33  gui__li  阅读(284)  评论(0编辑  收藏  举报