【模板】LCA

传送门:洛谷-【模板】最近公共祖先(LCA)


倍增版:

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;

int n,m,s,x,y,f[N][18],bin[20],d[N];
int head[N],to[N<<1],nxt[N<<1],tot;
int df[N];

inline void lk(int u,int v)
{to[++tot]=v;nxt[tot]=head[u];head[u]=tot;}

inline void dfs(int x)
{
    for(int i=1;bin[i]<=d[x];i++)
      f[x][i]=f[f[x][i-1]][i-1];
    for(int i=head[x];i;i=nxt[i]){
        if(to[i]==f[x][0]) continue;
        d[to[i]]=d[x]+1;f[to[i]][0]=x;
        dfs(to[i]);
    }
}

inline int lca(int x,int y)
{
    if(d[x]<d[y]) swap(x,y);
    int t=d[x]-d[y];
    for(int i=0;bin[i]<=t;i++)
        if(bin[i]&t) x=f[x][i];
    for(int i=17;i>=0;i--){
        if(f[x][i]!=f[y][i])
         x=f[x][i],y=f[y][i];
    }
    if(x==y) return x;
    return f[x][0];
}

int main(){
    bin[0]=1;
    for(int i=1;i<20;i++) bin[i]=bin[i-1]<<1;
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1;i<n;i++){
       scanf("%d%d",&x,&y);
       lk(x,y);lk(y,x); 
    }
    dfs(s);
    while(m--){
       scanf("%d%d",&x,&y);
       printf("%d\n",lca(x,y));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/corsica6/article/details/80303556