#include <bits/stdc++.h>
#define N 500005
using namespace std;
int head[N], ver[N << 1], nex[N << 1];
int n, m, Root, tot, t, f[N][19], d[N];
void add(int x, int y) {
ver[++tot] = y;
nex[tot] = head[x];
head[x] = tot;
}
void Deal_First(int Root) {
queue <int> q;
q.push(Root);
d[Root] = 1;
while (!q.empty()) {
int x = q.front();
q.pop();
for (int i = head[x]; i; i = nex[i]) {
int y = ver[i];
if (d[y])
continue;
d[y] = d[x] + 1;
f[y][0] = x;
for (int j = 1; j <= t; ++j) f[y][j] = f[f[y][j - 1]][j - 1];
q.push(y);
}
}
}
int LCA(int x, int y) {
if (d[x] > d[y])
swap(x, y);
for (int i = t; i >= 0; --i) {
if (d[f[y][i]] >= d[x])
y = f[y][i];
if (x == y)
return x;
}
for (int i = t; i >= 0; --i)
if (f[x][i] != f[y][i])
x = f[x][i], y = f[y][i];
return f[x][0];
}
int main() {
cin >> n >> m >> Root;
t = (int)log2(n);
for (int i = 1; i < n; ++i) {
int x, y;
scanf("%d %d", &x, &y);
add(x, y), add(y, x);
}
Deal_First(Root);
for (int i = 1; i <= m; ++i) {
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", LCA(x, y));
}
return 0;
}
算法标签:倍增。
时间复杂度: O ( ( n + m ) log n ) O((n+m)\log n) O((n+m)logn)