• LCA


    (LCA)

    (LCA)即最近公共祖先,在我们进行树上的某些毒瘤操作的时候,常常需要知道它的值,因此就出现了许多用来求(LCA)的代码。

    倍增

    而倍增则是其中最好写,最好理解,支持的操作比较多(比树链剖分要少)的一个算法了,所以本文只介绍该算法才不是因为我不会

    思想

    思想顾名思义就是倍增了,如果你深刻理解了(ST)表的思想的话,这个应该并不难理解。就是首先预处理出(fa[i][j])

    表示(i)这个点跳(2^j)步所跳到的节点,那就能很轻易地得到(fa[i][j]) = (fa[fa[i][j - 1]][j-1]),有没有发现这个很像(ST)表里的预处理,没错,就是因为他们都用了倍增这一思想。在预处理完之后,查询的时候就可以拿出来用了,在查询时,还是要用到倍增的思想,否则预处理这些数组就没有用了。然后就需要注意代码细节了

    代码

    预处理
    void dfs(int now, int f, int d)
    {
    	deep[now] = d; fa[now][0] = f;
    	for (int i = lin[now]; i; i = e[i].nex)
    		if (e[i].to != f)//不能回到父节点
    			dfs(e[i].to, now, d + 1);
    }
    inline void init()
    {
    	dfs(root, -1, 0);//可以令根的父亲为-1
    	for (int j = 0; j <= maxlog; j++)//j最大不能超过maxlog
    		for (int i = 1; i <= n; i++)
    			if (fa[i][j] < 0) fa[i][j + 1] = -1;
    			else fa[i][j + 1] = fa[fa[i][j]][j];//预处理核心部分
    }
    
    查询
    int lca(int u, int v)
    {
        if(deep[u] > deep[v])//来让v处于深度较高的地方,方便操作
            swap(u, v);
        for(int k = 0; k <= maxlog; k++)
            if((deep[v] - deep[u]) >> k & 1),我们用二进制来表示deep差,来快速转移到同意深度
                v = fa[v][k];
        if(u == v)
            return u;
        for(int k = maxlog; k >= 0; k--)
            if(fa[v][k] != fa[u][k])
                u = fa[u][k], v = fa[v][k];	
        return fa[u][0];
    }
    
  • 相关阅读:
    实现类莫名的错误解决
    xml文件不识别dubbo标签,添加支持的方法
    不要粗心马虎,不然你要付出几倍的精力纠错
    redis 缓存功能摘要
    spring的maven工程(服务层和表现层分离)配置浅析
    暂时放弃dubbo
    Maven工程的JDK版本配置
    spring的SOA聚合工程应用框架的搭建
    阿里云用宝塔面板安装JDK、zookeeper、dubbo
    maven项目不能正常运行
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/9905359.html
Copyright © 2020-2023  润新知