Tarjan是一个很厉害的人,不少算法(包括一些数据结构比如splay)都是他发明的…
Tarjan求LCA是利用并查集的思想进行操作的
首先我们有如下的思路
void Tarjan(int u){
fa[u]=u;
for(register int i=head[u];i;i=line[i].nxt){
int v=line[i].to;
if(v!=father[u]){
Tarjan(v);
fa[v]=u;
}
}
for(register int i=head_question[u];i;i=question[i].nxt){
int v=question[i].to;
if(!fa[v]) question[i].lca=find(v);
}
}
如果没有学过Tarjan求LCA的朋友看这里可能会有一些看不懂,现在我来解释一下其中的变量和数组的含义已经算法的大概思路
数据结构讲解:
首先 fa 数组表示的并查集中的那个 fa ,而 father 数组是在先前的 dfs 遍历的时候处理出来了的树上的 father , head 数组和 line 数组存的是树形结构的边(这里是邻接表结构),而 headquestion 和 question 存的是问题的那条链的首尾处(也就是询问的那两个点的 LCA ), question[i].lca 存的是该询问的 lca ,那么显然这两个数据结构应该是这样的
struct Line{
int val,from,to,nxt;
};
以及
struct question{
int from,to,lca,nxt;
};
显然这是一个离线算法&