LCA求法的三度升级

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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值