倍增求解LCA有bug
  • 板块学术版
  • 楼主hjqhs
  • 当前回复6
  • 已保存回复6
  • 发布时间2023/4/29 14:39
  • 上次更新2023/10/23 17:16:16
查看原帖
倍增求解LCA有bug
724988
hjqhs楼主2023/4/29 14:39
//O((n+q)logn)
//预处理O(nlogn) 单次询问O(logn)
#include<bits/stdc++.h>
#define maxn 1005
using namespace std;
int n,q,rt,dep[maxn],anc[maxn][18];
//anc[u][i]表示节点u的2^i级祖先
vector<int>g[maxn];
void dfs(int u,int f){
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v==f)continue;
        dep[v]=dep[u]+1;
        anc[v][0]=u;//一个节点的2^0=1级祖先就是它的父节点
        dfs(v,u);
    }
}
void init(){//统一处理出每个点的2^i级祖先
    for(int j=1;j<=18;j++)//这里的18指O(logn)
        for(int i=1;i<=n;i++)
            anc[i][j]=anc[anc[i][j-1]][j-1];
}
int queryLCA(int u,int v){
    if(dep[u]<dep[v])swap(u,v);
    for(int i=18;i>=0;i--)
        if(dep[anc[u][i]]>=dep[v])
            u=anc[u][i];
    //从大到小枚举二进制位,将较深的结点往上提
    if(u==v)return u;
    for(int i=18;i>=0;i--)
        if(anc[u][i]!=anc[v][i])
            u=anc[u][i],v=anc[v][i];
    //然后用相同的办法提两个点,直到相同为止
    return anc[u][0];
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>q>>rt;
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dep[rt]=1;
    dfs(rt,0);
    init();
    for(int i=1;i<=q;i++){
        int u,v;
        cin>>u>>v;
        cout<<queryLCA(u,v)<<'\n';
    }
    return 0;
}
2023/4/29 14:39
加载中...