LCA求法的三度升级

来源:互联网 发布:lol总是网络断开连接 编辑:程序博客网 时间:2024/04/29 06:09

1.RMQ做法:

    可见:学会用rmq解决lca问题

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运输计划)就可以体现优势。

但是该做法同样会被卡点(除非完全随机化),所以应根据题目有所选择。


0 0