zoukankan      html  css  js  c++  java
  • LCA基础 附例题(落谷)

    https://www.luogu.org/problemnew/solution/P3379

    LCA叫做最短公共祖先,用来求距离树上两个节点最近的公共点;

    常用倍增算法:

    #include<iostream>
    #include<cstdio>
    #include<vector>
    using namespace std;
    const int N=1E6+7;
    long long bits[30];
    int depth[N],fa[N][30];
    vector<int >ve[N];
    //"---------预处理部分---------"
    void inint(){
        bits[0]=1;
        for(int i=1;i<30;i++) bits[i]=bits[i-1]<<1;//用一个数组记录2的i次幂,每次向上爬满足条件的2的最大i次幂 
    }
    void dfs(int x,int y){//x为子节点,y为父节点 
        depth[x]=depth[y]+1;//子节点与父节点的关系 
        fa[x][0]=y;
        //"----核心之一 --"
        for(int i=1;i<30;i++)    fa[x][i]=fa[fa[x][i-1]][i-1]; 
        //"-------"每次向上爬2的i次幂相当于先爬2的i-1次幂,在爬2的i-1次幂 
        for(int i=0;i<ve[x].size();i++){//临接表存图与x相联的点出了子节点就是父节点。将父节点排除掉 
            int x1=ve[x][i];
            if(x1!=y){
                dfs(x1,x);//让x做父节点,x1做子节点 
            }
        }
    }
    //"-----------------------------------" 
    int lca(int x,int y){//我们规定x为较深的点,y为较浅的一个点 
        if(depth[x]<depth[y]) swap(x,y);//如果说depth[x]小的话,,要交换一下; 
        int dif=depth[x]-depth[y]; 
        for(int i=29;i>=0;i--){
            if(dif>=bits[i]){//将X和y变成同一高度。因就相当于将dif用二进制划分,然后记录一下x此时的位置 
                x=fa[x][i];
                dif=dif-bits[i];
            }
        }
        if(x==y) return x;//如果二者相等了说明二者在树枝的同一侧,y就是x的最近的根 
        for(int i=29;i>=0;i--){
            if(depth[x]>=bits[i]&&fa[x][i]!=fa[y][i]){//找到x和y的根的第一子节点 
                x=fa[x][i];
                y=fa[y][i];
            }
        }
        return fa[x][0];//返回自已子节点的父节点,就是公共根了 
    }
    
    int main(){
        inint();
        int n,m,s;
        scanf("%d%d%d",&n,&m,&s);
        int x,y;
        for(int i=1;i<=n-1;i++){
            scanf("%d%d",&x,&y);
            ve[x].push_back(y);
            ve[y].push_back(x);
        }
        dfs(s,0);//在这里s是总的根节点,我们规定如果越界,记为0,比如s的父节点就越界了,记录为0; 
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
  • 相关阅读:
    MongoDB,无模式文档型数据库简介
    数据说话:怎样的程序员最抢手?
    猛醒:也许我们一生追求的都错了!
    中国风电生产监控平台界面
    如何跟着趋势去赚钱
    2015年最好的员工心态培养 -- 我们需要把简单的事情做到极致
    什么是程序员的核心竞争力?
    第一篇 技术选型
    .net core 读取配置文件
    .net core nlog记录日志
  • 原文地址:https://www.cnblogs.com/Accepting/p/11322155.html
Copyright © 2011-2022 走看看