萌新蒟蒻求问LCA
  • 板块灌水区
  • 楼主Janokay
  • 当前回复8
  • 已保存回复8
  • 发布时间2022/1/21 22:38
  • 上次更新2023/10/28 11:37:04
查看原帖
萌新蒟蒻求问LCA
477588
Janokay楼主2022/1/21 22:38

https://www.luogu.com.cn/problem/P3379

附代码,样例没问题,点全错

#include <bits/stdc++.h>

using namespace std;

const int N = 500010, M = 2 * N;

int n, m, root; // root是根节点
int h[N], e[M], ne[M], idx; // 邻接表
//depth[i]即i的深度,fa[i][j]即是i往上走i^j所到达的节点
int depth[N], fa[N][16]; 
//静态队列
int q[N];

void add(int a, int b) { // 加边函数
    e[idx] = b; ne[idx] = h[a]; h[a] = idx ++ ;
}

void bfs(int root) { // 初始化
    memset(depth, 0x3f, sizeof depth);
    depth[0] = 0; depth[root] = 1;
    int hh = 0, tt = 0;
    q[0] = root;
    while ( hh <= tt ) {
        int t = q[hh ++ ];
        for ( int i = h[t]; ~i; i = ne[i] ) {
            int j = e[i];
            if ( depth[j] > depth[t] + 1 ) {
                depth[j] = depth[t] + 1;
                q[++ tt] = j;
                fa[j][0] = t;
                for ( int k = 1; k <= 15; k ++ )
                    fa[j][k] = fa[fa[j][k - 1]][k - 1];
            }
        }
    }
}

int lca(int a, int b) {
    if ( depth[a] < depth[b] ) swap(a, b); // 确保a是较深的节点
    // a ,b 应先跳到同一层
    for ( int k = 15; k >= 0; k -- ) {
        if ( depth[fa[a][k]] >= depth[b] )
            a = fa[a][k];
    }
    if ( a == b ) return a; 
    // a, b同时往上跳
    for ( int k = 15; k >= 0; k -- ) {
        if ( depth[fa[a][k]] != depth[fa[b][k]] ) {
            a = fa[a][k]; b = fa[b][k];
        }
    }
    return fa[b][0];
}

int main() {
    memset(h, -1, sizeof h); // 邻接表初始化
    scanf("%d%d%d", &n, &m, &root);
    for ( int i = 1; i <= n - 1; i ++ ) {
        int x, y; scanf("%d%d", &x, &y);
        add(x, y); add(y, x);
    }
    bfs(root);
    for ( int i = 1; i <= m; i ++ ) {
        int a, b; scanf("%d%d", &a, &b);
        printf("%d\n", lca(a, b));
    } 
    return 0;
}

求佬解惑

2022/1/21 22:38
加载中...