最近公共祖先模板(倍增思想

先上传送门:P3379 【模板】最近公共祖先(LCA) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)icon-default.png?t=M85Bhttps://www.luogu.com.cn/problem/P3379

最近公共祖先可以和很多点结合,比如和最小生成树(毒瘤):

P3366 【模板】最小生成树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)icon-default.png?t=M85Bhttps://www.luogu.com.cn/problem/P3366最近公共祖先一般都采用倍增优化:

import java.io.*;
import java.util.*;

public class Main {
    static int maxn=500001; // also maxm
    static int n,m,s,cnt;
    static int[] vv=new int[maxn<<1],to=new int[maxn<<1],he=new int[maxn<<1];
    static int[] lg=new int[maxn],depth=new int[maxn];
    static int[][] fa = new int[maxn][22];
    public static void main(String[] args) throws IOException {
        n=nextInt();m=nextInt();s=nextInt();
        for(int i=1;i<=n;i++)
            lg[i]=lg[i-1]+(1<<lg[i-1]==i?1:0);
        for(int i=1;i<n;i++){
            int x=nextInt(),y=nextInt();
            addEdge(x,y);
            addEdge(y,x);
        }
        dfs(s,0);
        for(int i=1;i<=m;i++){
            int x=nextInt(),y=nextInt();
            int ans=lca(x,y);
            out.println(ans);
        }
        out.flush();
    }
    public static void dfs(int now,int fath){
        fa[now][0]=fath;depth[now]=depth[fath]+1;
        for(int i=1;i<=lg[depth[now]];i++)
            fa[now][i]=fa[fa[now][i-1]][i-1];
        for(int i=he[now];i>0;i=to[i])
            if(vv[i]!=fath) dfs(vv[i],now);
    }

    public static int lca(int x,int y){
        if(depth[x]<depth[y]) {int tmp=x;x=y;y=tmp;}
        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];
    }


    public static void addEdge(int u,int v){
        vv[++cnt]=v;
        to[cnt]=he[u];
        he[u]=cnt;
    }
    static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

    static int nextInt() throws IOException {
        in.nextToken();
        return (int)in.nval;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玛卡左家陇分卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值