[模板] 树链剖分找LCA

#include <cstdio>
#include <cstring>
#define MAX 500005

int d[MAX],fa[MAX],size[MAX],top[MAX],son[MAX];
int N,M,S,tot=0;
int head[MAX];

struct edge{
    int v,next;
}G[MAX<<1];

inline void add(int u,int v){
    G[++tot].v=v;G[tot].next=head[u];head[u]=tot;
}

inline void dfs1(int u,int father){
    d[u]=d[father]+1;
    fa[u]=father;
    size[u]=1;
    int max = 0;
    for(register int i=head[u];i;i=G[i].next){
        int v = G[i].v;
        if(v==father)continue;
        dfs1(v,u);
        size[u]+=size[v];
        if(size[v]>max)son[u]=v,max=size[v];
    }
}

inline void dfs2(int u,int high,int father){
    top[u]=high;
    if(son[u]==0)return;
    dfs2(son[u],high,u);
    for(register int i=head[u];i;i=G[i].next){
        int v = G[i].v;
        if(v==son[u]||v==father)continue;
        dfs2(v,v,u);
    }
}

inline void swap(int* u,int* v){
    int t = *u;*u = *v;*v = t;
}

inline int LCA(int u,int v){
    while(top[u]!=top[v]){
        if(d[top[u]]<d[top[v]])swap(&u,&v);
        u = fa[top[u]];
    }
    return d[u]>d[v]?v:u;
}
int main(){

    std::memset(head,0,sizeof(head));
    std::memset(son,0,sizeof(son));
        
    scanf("%d%d%d",&N,&M,&S);
    int u,v;
    for(register int i=1;i<N;++i){
        scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    
    d[0]=0;
    
    dfs1(S,0);
    dfs2(S,S,0);
    
    for(register int i=1;i<=M;++i){
        scanf("%d%d",&u,&v);
        printf("%d\n",LCA(u,v));
    }
    return 0;
}
 

转载于:https://www.cnblogs.com/Neworld2002/p/8641002.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值