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;
}
求佬解惑