zoukankan      html  css  js  c++  java
  • 倍增 [模板]最近公共祖先LCA

    本人水平有限,题解不到为处,请多多谅解

    本蒟蒻谢谢大家观看

    题目:传送门

    倍增求LCA模板

    code:

    #include<bits/stdc++.h>
    #pragma GCC optimize(3)
    using namespace std;
    int n,q,a,b,tot,m;
    int nxt[1000010],head[1000010],ver[1000010],dep[1000010],f[1000010][21];
    //设f[x,k]表示x的2^k辈祖先,即从x向根节点走2^k步到达的节点
    inline int read()
    {    
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*f;
    }
    void put(int x,int y)
    {
        ++tot;
        ver[tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    void dfs(int x,int fa)//预处理 深度及到达根节点的步数 
    {
        dep[x]=dep[fa]+1;//初始化深度 
        for(int i=0;i<=19;i++){//或者 i=1;i<=20;i++
            f[x][i+1]=f[f[x][i]][i];//f[x][i]=f[f[x][i-1]][i-1]
            //注意:当i=1 to 20 时    f数组要都要开21,否则会爆零
        }
        for(int i=head[x];i;i=nxt[i])
        {
            int y=ver[i];
            if(y==fa)continue;
                f[y][0]=x;
                //y向上跳2^0=1就是x,因为y是x的子节点 
                dfs(y,x);
        }
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])//使x深度大于y 
            swap(x,y);
        for(int i=20;i>=0;i--){//一定要写逆循环 
            if(dep[f[x][i]]>=dep[y])//把x向上调整到与y同一深度
                x=f[x][i];
        } 
            if(x==y)//如果在同一分支上,直接输出,因为此时x,y的LCA即本身 
                return x; 
        for(int i=20;i>=0;i--){ //此时x,y已跳到同一层
            if(f[x][i]!=f[y][i]){  
            //如果f[x][i]和f[y][i]不同才跳,因为相同就表示已经找到根节点 
                x=f[x][i];//不断更新 
                y=f[y][i];//不断更新 
            }
        }
        return f[x][0];//当无法在跳时,根节点(父亲节点) 距离字节点只有一步 
    }
    int main()
    {
         n=read(),q=read(),m=read();
        for(int i=1;i<n;i++)
        {
            a=read(),b=read();
            put(a,b);
            put(b,a);
        }
        dfs(m,0);//以m为根开始遍历 
        for(int i=1;i<=q;i++)
        {
            a=read(),b=read();
            printf("%d
    ",lca(a,b));
        }
        return 0;
    }
  • 相关阅读:
    Sparrow 开发板化身电脑音量调节器
    我的第一台台式机
    DFRobot万物互联大赛第二轮
    DFRobot万物互联大赛第一轮
    RPi Cam v2 之一:基础及牛刀小试
    Galileo Gen2 之MQTT通讯
    路飞学城Python爬虫课第一章笔记
    Micro:Bit手柄试用之一MagicPad (解决蓝牙与gamePad包共存)
    PocketBeagle 初高级设置
    EVB-P6UL:一识庐山真面目
  • 原文地址:https://www.cnblogs.com/nlyzl/p/11562223.html
Copyright © 2011-2022 走看看