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

我的未来我决定 提交于 2019-12-07 01:15:31

给一手链接 https://www.luogu.com.cn/problem/P3379

算是lca的模板吧

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int M=1e6+7;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int deep[M],f[M][27],vis[M];
int n,m,S,first[M],cnt;
struct node{int to,next;}e[2*M];
void ins(int x,int y){e[++cnt]=(node){y,first[x]}; first[x]=cnt;}
void dfs(int x){
    vis[x]=1;
    for(int i=1;(1<<i)<=deep[x];i++) f[x][i]=f[f[x][i-1]][i-1];
    for(int i=first[x];i;i=e[i].next){
        int now=e[i].to;
        if(!vis[now]){
            deep[now]=deep[x]+1;
            f[now][0]=x;
            dfs(now);
        }
    }
}
int find(int x,int y){
    if(deep[x]<deep[y]) swap(x,y);
    int d=deep[x]-deep[y];
    for(int i=0;(1<<i)<=d;i++) if(d&(1<<i)) x=f[x][i];
    if(x==y) return x;
    for(int i=30;i>=0;i--)
    if((1<<i)<=deep[x]&&f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}
int main(){
    int x,y;
    n=read(); m=read(); S=read();
    for(int i=1;i<n;i++) x=read(),y=read(),ins(x,y),ins(y,x);
    dfs(S);
    for(int i=1;i<=m;i++) x=read(),y=read(),printf("%d\n",find(x,y));
    return 0;
}
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!