LCA主要是用来处理当两个点仅有唯一一条确定的最短路径时的路径。
点本身或者其父亲节点也可以作为祖先节点。
朴素DFS:
Tarjan(离线)算法
一次预处理出所有询问的结果,时间复杂度为O(n+q)
DFS+并查集
1.任选一个点为根节点
2.从根节点开始。遍历该点u所有子节点v,并标记这些子节点v已被访问过。
3.若是v还有子节点,返回2,否则下一步。
4.合并v到u上
5.寻找与当前点u有询问关系的点v。
6.若是v已经被访问过了,则可以确认u和v的最近公共祖先为v被合并到的父亲节点a。
Tarjan(u)//merge和find为并查集合并函数和查找函数
{
for each(u,v) //访问所有u子节点v
{
Tarjan(v); //继续往下遍历
merge(u,v); //合并v到u上
标记v被访问过;
}
for each(u,e) //访问所有和u有询问关系的e
{
如果e被访问过;
u,e的最近公共祖先为find(e);
}
}