Algoritmo e estrutura de dados -- LCA/antepassado comum mais próximo

#include<cstdio>
#include<vector>
#include<queue>
using namespace std;

int n,m,s;
vector<int> edge[500005];
int depth[500005];
int anc[500005][20];

void dfs(int now, int fa){
    depth[now]=depth[fa]+1;
    anc[now][0] = fa;
    for(int i=1;(1<<i)<=depth[now]-1;i++){
        anc[now][i] = anc[anc[now][i-1]][i-1];
    }
    for(int i=0;i<(int)edge[now].size();i++){
        int nxt = edge[now][i];
        if(nxt==fa) continue;
        dfs(nxt, now);
    }
}

int lca(int x, int y){
    if(depth[x]<depth[y]) swap(x,y);
    if(depth[x]!=depth[y]){
        for(int i=20;i>=0;i--){
            if((1<<i)<=depth[x]-depth[y]){
                x = anc[x][i];
            }
        }
    }
    if(x==y) return x;
    for(int i=20;i>=0;i--){
        if((1<<i)>depth[x]-1) continue;
        if(anc[x][i]==anc[y][i]) continue;
        x = anc[x][i];
        y = anc[y][i];
    }
    return anc[x][0];
}

int main()
{
    scanf("%d%d%d",&n,&m,&s); //n个点,m条边,s是根节点
    for(int i=1;i<=n-1;i++){
        int x,y;scanf("%d%d",&x,&y);
        edge[x].push_back(y);
        edge[y].push_back(x);
    }
    dfs(s,0);  // 预处理每个节点的深度和第2^i级祖先
    for(int i=1;i<=m;i++){
        int x,y;scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y)); // 倍增法计算两个节点的最近公共祖先
    }
    return 0;
}

referência:

C++ P3379 [Modelo] Antepassado Comum Mais Próximo (LCA)_C++ Código do Antepassado Comum Mais Próximo_Object_S' Blog-CSDN Blog

Resumo de alguns pontos sobre o algoritmo LCA (método de multiplicação) - Object_S Blog - CSDN Blog

Supongo que te gusta

Origin blog.csdn.net/qq_41021141/article/details/131344284
Recomendado
Clasificación