#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