zoukankan      html  css  js  c++  java
  • 图论--倍增lca(一直没写代码实现)

    如题,原来听了怎么实现,一直没有写过,然后这是提高里会出现的,于是来补一下(好像我要补的还很多啊^_^)
    给大家放一道题:洛谷 P3379 【模板】最近公共祖先(LCA)
    温馨提示:这题卡常^_^
    代码:(具体看注释)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #include<vector>
    #include<queue>
    using namespace std;
    inline void read(int &x){//据说这是最快的读入
        char ch=' ';
        while(!isdigit(ch=getchar()));
        x=ch-'0';
        while(isdigit(ch=getchar())){
            x=x*10+ch-'0';
        }
    }
    int n,m,s;
    struct edge{//邻接表存储,卡常用
        int to,next;
    }e[1000001];//无向图开两倍
    //st[k][i]代表从i跳2^k步可以跳到的位置
    int st[20][500001],dep[500001],head[500001];//st表,深度,还有邻接表
    inline void dfs(int x,int fa,int d){//dfs初始化父亲和深度
        st[0][x]=fa;
        dep[x]=d;
        for(register int i=head[x];i;i=e[i].next){//register卡常,以下省略
            if(e[i].to!=fa)dfs(e[i].to,x,d+1);
        }
    }
    void getst(){初始化st表
        dfs(s,0,1);//dfs初始化
        for(register int k=0;k<19;k++){
            for(register int i=1;i<=n;i++){
                st[k+1][i]=st[k][st[k][i]];//解释一下这步:先跳2^k步,再跳2^k步,一共就跳了2^(k+1)步
            }
        }
    }
    inline int lca(int x,int y){
        if(dep[x]>dep[y]){//保证y的深度较大
            swap(x,y);
        }
        for(register int k=19;k>=0;k--){
            if(dep[st[k][y]]>=dep[x]){//如果跳不超过,就跳
                y=st[k][y];
            }
        }
        if(x==y)return x;
        for(register int k=19;k>=0;k--){
            if(st[k][x]!=st[k][y]){//如果跳不超过,就跳
                x=st[k][x];
                y=st[k][y];
            }
        }
        return st[0][x];//这时一定只需要再跳一步了
    }
    int tot;
    inline void addedge(int x,int y){//inline优化
        tot++;
        e[tot].to=y;
        e[tot].next=head[x];
        head[x]=tot;
    }
    int main(){
        read(n);
        read(m);
        read(s);
        for(register int i=1;i<=n-1;i++){
            int x,y;
            read(x);
            read(y);
            addedge(x,y);
            addedge(y,x);
        }
        getst();
        for(register int i=1;i<=m;i++){
            int x,y;
            read(x);
            read(y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
  • 相关阅读:
    mysql dump 完全备
    CentOS7位安装MySql教程
    mysql 数据备份
    Linux下iostat命令详解
    端口映射
    git+jenkins jar包代码的发布加新建项目
    腾讯面试题
    PHP-----类与对象,成员方法,成员属性,构造方法,析构方法
    PHP-----二维数组和二分查找
    PHP-----数组和常见排序算法
  • 原文地址:https://www.cnblogs.com/stone41123/p/7581281.html
Copyright © 2011-2022 走看看