1.RMQ做法:
2.倍增做法:
可见:LCA倍增
3.轻重路径剖分法:
轻重路径剖分基础:树链剖分(无需看剖分过程,重点搞清楚什么是轻重路径)
那么,具体过程可以类比剖分的query过程:
<span style="font-size:24px;">void dfs1(int u){
dep[u]=dep[fa[u]]+1;
int Max=0;
for (int p=a[u];p;p=e[p].next)
if (e[p].j!=fa[u]){
int j=e[p].j;
dis[j]=dis[u]+e[p].v;
fa[j]=u;
dfs1(j);
size[u]+=size[j];//统计子节点的个数
if (size[u]>Max){//选择子节点的儿子继续传递重路径
Max=size[u];
son[u]=j;
}
}
}
</span>
<span style="font-size:24px;">void build(int u,int tp){
top[u]=tp;
if (son[u])build(son[u],tp);//选择子节点最多的儿子继续传递重路径
for (int p=a[u];p;p=e[p].next)
if (e[p].j!=fa[u] && e[p].j!=son[u])build(e[p].j,e[p].j);//其余儿子自开一条重路径
}//构建轻重路径
int LCA(int u,int v){
int fu=top[u],fv=top[v];//都爬到各自重路径的顶端
while (fu != fv){
if (dep[fu]<dep[fv])swap(fu,fv),swap(u,v);
u=fa[fu];fu=top[u];//不断沿重路径向上爬
}
return dep[u]<dep[v]?u:v;//此时在同一重路径中,深度浅的即为LCA
}</span>
该做法的效率同为logn,但常数更优,在某些卡点的题目中(如NOIP2015运输计划)就可以体现优势。
但是该做法同样会被卡点(除非完全随机化),所以应根据题目有所选择。