• 关于树论【LCA树上倍增算法】


    补了一发LCA,表示这东西表面上好像简单,但是细节真挺多。

    我学的是树上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爷爷)有一个跟st表非常类似的东西,f[i][j]表示j的第2^i的祖先,就是说f[0][x]是父亲,f[1][x]是爷爷,f[2][x]是高祖父(爷爷的爷爷),f[3][x]是远祖父(高祖父的高祖父)

    搞个事:

    按古制辈份分为自己,父亲、祖父、曾祖、高祖、天祖、烈祖、太祖、远祖、鼻祖。

    扯回来,这个就是倍增的思想,可以方便的实现O(logn)的LCA,现在让你在构图的时候搞好f数组,一点问题都没有了吧~

    然后怎么求LCA?首先,我们先让深度比较深的点往上跳,然后两个一起跳,直到跳到父亲相同。那我们跳的时候,就像二进制一样,可以一次跳2^i次方

    caioj1236:(赤裸裸的LCA)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct node
    {
        int x,y,next;
    }a[210000];int len,last[110000];
    void ins(int x,int y)
    {
        a[++len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    //f[i][j]表示j的第2^i的祖先
    int Bin[30],dep[110000],f[25][110000];
    void dfs(int x,int fa)//构树 
    {
        f[0][x]=fa;//x的2^0=1就是自己父亲 
        for(int i=1;Bin[i]<=dep[x];i++)f[i][x]=f[i-1][f[i-1][x]];//倍增,爸爸的爸爸是爷爷 
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fa)
            {
                dep[y]=dep[x]+1;
                dfs(y,x);
            }
        }
    }
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);//让比较深的先往上跳 
        for(int i=20;i>=0;i--)//倒着,想象成二进制,比如要找第5个祖先,就变成101,从左往右把所有为一的跳一下 
            if(dep[x]-dep[y]>=Bin[i])x=f[i][x];
        if(x==y)return x;
        for(int i=20;i>=0;i--)//深度一样了,x和y一起跳
            if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y]){x=f[i][x];y=f[i][y];}
        return f[0][x];
    }
    int main()
    {
        Bin[0]=1;for(int i=1;i<=25;i++)Bin[i]=Bin[i-1]*2;
        int n,m,x,y;
        scanf("%d%d",&n,&m);
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            ins(x,y);ins(y,x);
        }
        dep[1]=1;dfs(1,0);
        while(m--)
        {
            scanf("%d%d",&x,&y);
            printf("%d
    ",LCA(x,y));
        }
        return 0;
    }
  • 相关阅读:
    HttpServletRequest对象(一)
    HttpServletResponse对象(二)
    HttpServletResponse对象(一)
    Servlet路径跳转问题
    sevlet的url-pattern设置
    java中使用相对路径读取文件的写法总结 ,以及getResourceAsStream() (转)
    创建第一个servlet程序--HelloServlet
    Eclipse创建一个JAVA WEB项目
    Servlet学习(二):ServletConfig获取参数;ServletContext应用:请求转发,参数获取,资源读取;类装载器读取文件
    Centos7默认安装的docker版本说明
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/7598784.html
Copyright © 2020-2023  润新知