P3379 【模板】最近公共祖先(LCA)

luogu P3379 LCA

题目链接

传送门

#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int nxt[N<<1],head[N],to[N<<1],tot;
void add(int u,int v)
{
    nxt[++tot] = head[u];
    head[u] = tot;
    to[tot] = v;
}
int depth[N],fa[N][23],lg[N];
void dfs(int u,int fath)
{
    fa[u][0] = fath;
    depth[u] = depth[fath] + 1;
    for(int i=1;i<=lg[depth[u]];i++)
    {
        fa[u][i] = fa[fa[u][i-1]][i-1];
    }
    for(int i=head[u];i;i=nxt[i])
    {
        if(to[i]!=fath)
            dfs(to[i],u);
    }
}
int LCA(int x,int y)
{
    if(depth[x]<depth[y])
        swap(x,y);
    while(depth[x]>depth[y])
    {
        x = fa[x][lg[depth[x]-depth[y]]-1];
    }
    if(x==y)
        return x;
    for(int k=lg[depth[x]]-1;k>=0;k--)
    {
        if(fa[x][k]!=fa[y][k])
            x = fa[x][k],y = fa[y][k];
    }
    return fa[x][0];
}
int main() {
    int n,m,start;
    scanf("%d%d%d",&n,&m,&start);
    for(int i=1;i<=n-1;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        add(v,u);
    }
    for(int i=1;i<=n;i++)
    {
        lg[i] = lg[i-1] + (1 << lg[i-1] == i);
    }
    dfs(start,0);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",LCA(x,y));
    }
    return 0;
}

posted @ 2020-03-13 20:43  hh13579  阅读(103)  评论(0编辑  收藏  举报