#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
const int maxm = 1e6 + 5;
struct edge {
int next, v;
}E[maxm];
int head[maxn];
int tot = 0;
int root;
void addedge(int u, int v) {
E[++tot].next = head[u];
E[tot].v = v;
head[u] = tot;
}
int dep[maxn];
int pa[maxn][25];
void dfs(int u, int depth) {
dep[u] = depth;
for (int i = head[u]; i; i = E[i].next) {
int v = E[i].v;
if (!dep[v] && v != root) {
pa[v][0] = u;
dfs(v, depth + 1);
}
}
}
void getparent(int n) {
for (int j = 1; j <= 20; j++) {
for (int i = 1; i <= n; i++) {
pa[i][j] = pa[pa[i][j - 1]][j - 1];
}
}
}
int lca(int u, int v) {
if (dep[u] < dep[v]) {//保证u比v深
swap(u, v);
}
int i = -1;
while (1 << (i + 1) <= dep[u]) {//确定最大跨度,保证不会越界
i++;
}
for (int j = i; j >= 0; j--) {//让u,v到达同一高度
if (dep[u] - (1 << j) >= dep[v]) {
u = pa[u][j];
}
}
if (u == v) {
return u;
}
for (int j = i; j >= 0; j--) {
if (pa[u][j] != pa[v][j]) {
u = pa[u][j];
v = pa[v][j];
}
}
return pa[u][0];
}
void debug(int* a, int l, int r) {
for (int i = l; i <= r; i++)cout << a[i] << " "; cout << endl;
}
int main() {
int n, m;
cin >> n >> m >> root;
for (int i = 1; i <= n - 1; i++) {
int u, v;
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
dfs(root, 0);
getparent(n);
for (int i = 1; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
int ans = lca(u, v);
printf("%d\n", ans);
}
}
来源:https://www.cnblogs.com/ucprer/p/12284672.html