• 图论--倍增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;
    }
  • 相关阅读:
    [转]中英文混合字符截取方法样式表解决方法
    Asp.Net小技巧集合
    [分享]整理后的Discuz!NT 2.0项目源码
    [原创]Web2.0之Tag标签原理实现浅析
    [转]CSS完美兼容IE6/IE7/FF的通用hack方法
    [转]常用CSS缩写语法总结
    文本类文件编码转换器及DiscuzNTdotNet2.0 - -
    [驳]ASP伪静态页简单教程
    SELECT中很多程序都不用的NOLOCK“加锁选项”的功能说明
    iOS 微博 OAuth2.0 分享 文字 + 图片 微博的方法
  • 原文地址:https://www.cnblogs.com/stone41123/p/7581281.html
Copyright © 2020-2023  润新知