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

    //LCA
    //倍增 在线 
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #define maxn 500001
    using namespace std;
    int n,m,root,cnt;
    int head[2*maxn],depth[maxn],f[maxn][21];//depth深度 f[a][b]指a节点的第2^b个祖先 
    struct uio{
        int next,to;
    }edge[2*maxn];
    int add(int x,int y)
    {
        edge[++cnt].next=head[x];
        edge[cnt].to=y;
        head[x]=cnt;
    }
    void dfs(int x)//求深度
    {
        for(int i=head[x];i!=-1;i=edge[i].next)
            if(!depth[edge[i].to])
            {
                depth[edge[i].to]=depth[x]+1;
                f[edge[i].to][0]=x;
                dfs(edge[i].to);
            }
    } 
    int init()//初始化f数组 
    {
        for(int i=1;(1<<i)<=n;i++)
            for(int j=1;j<=n;j++)
                f[j][i]=f[f[j][i-1]][i-1];
    }
    int lca(int x,int y)
    {
        if(depth[x]<depth[y])
            swap(x,y);
        int d=depth[x]-depth[y];
        for(int i=0;(1<<i)<=d;i++)
            if((1<<i)&d)
    //    for(int i=0;d;i++,d<<=1)//第二种写法 
    //        if(d&1)
                x=f[x][i];
        if(x!=y)
        {
            for(int i=20;i>=0;i--)
                if(f[x][i]!=f[y][i])//f[x][i]==f[y][i] --> lca在此祖先下方或者是此祖先
                                    //f[x][i]!=f[y][i] --> lca在此祖先上方 
                    x=f[x][i],y=f[y][i];
            return f[x][0];
        }
        else
            return x;  
    } 
    int main()
    {
        memset(head,-1,sizeof(head));
        scanf("%d%d%d",&n,&m,&root);
        for(int i=1;i<=n-1;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        } 
        depth[root]=1;
        dfs(root);
        init();
        for(int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            printf("%d
    ",lca(u,v));
        }
        return 0;
    }
  • 相关阅读:
    win8 tips
    从win10体验到重装win8
    win10 体验 日志
    磁盘分区与多系统安装(windows ubuntu)
    使用ultraISO制作ISO镜像文件
    C++中const用法总结
    4月8号的打卡
    Java第二次作业
    第一次Java作业
    NX二次开发-改变自制UI界面大小
  • 原文地址:https://www.cnblogs.com/water-radish/p/9280515.html
Copyright © 2011-2022 走看看