倍增求LCA

时间:2019-09-03
本文章向大家介绍倍增求LCA,主要包括倍增求LCA使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

#include<bits/stdc++.h>
struct node
{
    int from,to,next;
}edge[1000001];
int n,m,s,head[1000001],num,depth[1000001],father[1000001][50];
void add(int u,int v)
{
    edge[++num].from=u;
    edge[num].to=v;
    edge[num].next=head[u];
    head[u]=num;
    return;
}

void Depth_First_Search(int now,int dep,int last)
{
    for(int i=head[now];i;i=edge[i].next)
        if(edge[i].to-last)
        {
            depth[edge[i].to]=dep+1;
            father[edge[i].to][0]=now;
            for(int j=1;(1<<j)<=depth[edge[i].to];j++)
                father[edge[i].to][j]=father[father[edge[i].to][j-1]][j-1];
            Depth_First_Search(edge[i].to,dep+1,now);
        }
        
    return;
}

int lca(int x,int y)
{
    if(depth[x]<depth[y])
        x^=y^=x^=y;
    while(depth[x]>depth[y])
        x=father[x][int(log2(depth[x]-depth[y]))];
    if(x==y)
        return x;
    for(int i=log2(depth[x]);i>=0;i--)
        if(father[x][i]-father[y][i])
        {
            x=father[x][i];
            y=father[y][i];
        }
        
    return father[x][0];
}

int main()
{
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1;i<=n-1;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    
    Depth_First_Search(s,0,0);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
    
    return 0;
}

原文地址:https://www.cnblogs.com/s-t-a-r-d-u-s-t/p/11455249.html