#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
int n, m, root;
int u, v;
vector<int> tmp;
vector<vector<int>> G(500010,tmp);
int depth[500010];
int jump[500010][21];
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
void Dfs(int x, int fa) {
for (int i = 0; i < G[x].size(); i++) {
int y = G[x][i];// 避免 4-3,3-4的情况
if (y != fa) {
depth[y] = depth[x] + 1;
jump[y][0] = x;
Dfs(y, x);
}
}
}
void Init() {
depth[root] = 1;
Dfs(root, 0);
for (int j = 1; (1 << j) <= n; j++)
for (int i = 1; i<= n; i++){
jump[i][j] = jump[jump[i][j - 1]][j - 1];
}
}
int Lca(int a, int b) {
if (depth[a] > depth[b])//让 b的深度 大于 a的深度
swap(a, b);
int k = log2(n);
for (int i = k; i >= 0; i--)
if (depth[jump[b][i]] >= depth[a])
b = jump[b][i];
if (a == b)
return a;
for (int i = k; i >= 0; i--)
if (jump[a][i] != jump[b][i]) {
a = jump[a][i];
b = jump[b][i];
}
return jump[a][0];
}
int main() {
n=read();
m=read();
root=read();
for (int i = 1; i <= n - 1; i++) {
u=read();
v=read();
G[u].push_back(v);
G[v].push_back(u);
}
Init();
for (int i = 1; i <= m; i++) {
u=read();
v=read();
printf("%d\n",Lca(u, v));
}
}
最近公共祖先 (倍增 大跳算法)
最新推荐文章于 2024-06-07 21:12:47 发布