zoukankan      html  css  js  c++  java
  • LCA 倍增

    #include<iostream>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 10086;
    int num[maxn];
    int bin[30];
    int deep[maxn];
    int q1,q2;
    int fa[maxn][30];
    vector<int>u[maxn];
    int root;
    
    void get_f()
    {
        for(int i=0;i<=20;i++){
            bin[i]=(1<<i);
        }
    }
    
    void build()//输入,建树,并找到根节点
    {
        int n;
        int x,y;
        scanf("%d",&n);
        for(int i=1;i<=n-1;i++){
            scanf("%d%d",&x,&y);
            u[x].push_back(y);
            num[y]++;
        }
        for(int i=1;i<=n;i++){
            if(!num[i]){
                root=i;
            }
        }
        scanf("%d%d",&q1,&q2);
    }
    
    void init()//初始化
    {
        memset(fa,0,sizeof(fa));
        memset(deep,0,sizeof(deep));
        memset(num,0,sizeof(num));
        for(int i=0;i<maxn;i++){
            u[i].clear();
        }
    }
    
    void bfs()//找出每个节点的深度,填写fa数组
    {
        queue<int>q;
        int cur;
        q.push(root);
        deep[root]=1;
        while(!q.empty()){
            cur=q.front();q.pop();
            for(int i=1;i<20;i++){
                if(deep[cur]<bin[i]){break;}
                fa[cur][i]=fa[fa[cur][i-1]][i-1];//现在这个节点的第2^i个爸爸
                                        //就是他的2^(i-1)个爸爸的第2^(i-1)个爸爸
            }
            int siz=u[cur].size();
            for(int i=0;i<siz;i++){
                q.push(u[cur][i]);
                fa[u[cur][i]][0]=cur;//亲爸爸
                deep[u[cur][i]]=deep[cur]+1;
            }
        }
    }
    
    int lca()
    {
        int x=q1,y=q2;
        if(deep[x]<deep[y]){swap(x,y);}
        int t=deep[x]-deep[y];
        for(int i=0;i<20;i++){
            if(t&bin[i]){x=fa[x][i];}
        }//化为相同深度
        for(int i=19;i>=0;i--){
            if(fa[x][i]^fa[y][i]){
                x=fa[x][i];
                y=fa[y][i];
            }
        }//如果第2^i个父节点不同,一同向上移动
        if(x==y){return x;}
        return fa[x][0];
    }
    
    int main()
    {
        int T;
        get_f();
        scanf("%d",&T);
        while(T--){
            init();
            build();
            bfs();
            printf("%d
    ",lca());
        }
        return 0;
    }
    

      代码可以AC POJ1330

  • 相关阅读:
    hdu 5059 判断数字表示方式以及范围合法(int型之内)
    hdu1024 最大m子序列和
    POJ 1573 Robot Motion 模拟 难度:0
    POJ 2632 Crashing Robots 模拟 难度:0
    POJ 1068 Parencodings 模拟 难度:0
    ncs安装及初次运行
    POJ 1328 Radar Installation 贪心 难度:1
    POJ 3094 Quicksum 难度:0
    django.test.client 使用随记
    POJ 2255 Tree Recovery 树的遍历,分治 难度:0
  • 原文地址:https://www.cnblogs.com/ZGQblogs/p/9508551.html
Copyright © 2011-2022 走看看