zoukankan      html  css  js  c++  java
  • LCA最近公共祖先倍增法笔记

     先暂时把模板写出来,A几道题再来补充

    此模板也是洛谷上的一道模板题

    P3379 【模板】最近公共祖先(LCA)

    #pragma GCC optimize(2) //o2优化
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int L = 30;//2的指数的大小 
    const int NN = 1e6+10;
    int N,M,S;
    
    ll bit[L];
    int depth[NN];//depth[i]:节点i在树上的深度 
    int fa[NN][L]; //fa[i][j]:节点i向上走2^j次方的节点 
    vector<int> G[NN];//存图 
    
    
    void init_log(){//预先把2的多少次方计算出来 
        bit[0] = 1;
        for(int i = 1;i<L;i++)
            bit[i] = bit[i-1]*2;
    }
    
    void DFS(int u,int par){//u:当前节点 par:u的父亲节点 
        depth[u] = depth[par]+1;
        fa[u][0] = par;
        for(int i = 1;i<L;i++){
            fa[u][i] = fa[fa[u][i-1]][i-1];//计算u的各次方的祖先 
        }
        for(auto v: G[u]){//继续去遍历该节点的孩子节点 
            if(v!=par){//因为是用邻接表存的,所以需要跳过父亲节点 
                DFS(v,u);
            }
        }
    }
    
    int LCA(int a,int b){
        if(depth[a] < depth[b]) swap(a,b);//保证深度大的在前,小的在后 
        int dif = depth[a] - depth[b];//深度差 
        for(int i = L-1;i>=0;i--){
            if(bit[i] <= dif){//在不超出深度差的范围向上爬 
                a = fa[a][i];//爬到的位置 
                dif -= bit[i];//深度差更新 
            }
        }
        //此时a,b已经是相同的深度
        if(a == b) return a; //如果a,b节点已经相同,所以a,b所在的节点就是lca 
        
        for(int i = L-1;i>=0;i--){
            if(bit[i] <= depth[a] && fa[a][i] != fa[b][i]){ //bit[i]<=depth[a]:表示不跳出树之外 
                a = fa[a][i];
                b = fa[b][i];
            }
        }
        return fa[a][0]; //返回lca的儿子的父亲,也就是lca 
    }
    
    
    int main(){
    //    freopen("test.in","r",stdin);
        init_log();
        cin>>N>>M>>S;
        int u,v;
        for(int i = 1;i<=N-1;i++){ //邻接表存图 
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        DFS(S,0);
        int a,b;
        for(int i = 1;i<=M;i++){
            scanf("%d%d",&a,&b);
            int lca = LCA(a,b);
            printf("%d\n",lca);
        }
        
        
        return 0;
    }
  • 相关阅读:
    一款可以下拉搜索html下拉框控件
    Springboot+JPA+Thymeleaf 校园博客完整小网站
    OAuth 2.0 认证的原理与实践
    BootStrap 专题
    Rest接口和Thymeleaf的两个坑
    Android属性动画PropertyAnimation LayoutTransition(布局容器动画)
    Android 5.0中使用JobScheduler
    遍历Map的四种方法
    Android Error:(1,N1) 错误: 需要class, interface或enum
    Android.app.SuperNotCalledException错误
  • 原文地址:https://www.cnblogs.com/bigbrox/p/11320187.html
Copyright © 2011-2022 走看看