voidgetFa(int u, int f){ fa[u][0] = f; dep[u] = dep[f] + 1; for (int i = 1; i <= 20; i++) fa[u][i] = fa[ fa[u][i - 1] ][i - 1]; for (int v : e[u]) { if (v == f) continue; getFa(v, u); } }
寻找 LCA
与朴素算法类似,不同之处是利用二进制和 fa 数组将复杂度从
\(O(n)\) 优化到 \(O(\log n)\)。
intlca(int u, int v){ if (dep[u] < dep[v]) std::swap(u, v); for (int i = 20; i >= 0; i--) { if (dep[ fa[u][i] ] >= dep[v] ) { u = fa[u][i]; } } if (u == v) return u; for (int i = 20; i >= 0; i--) { if (fa[u][i] != fa[v][i]) { u = fa[u][i]; v = fa[v][i]; } } return fa[u][0]; }
int n; std::vector<int> e[MAXN + 1]; int fa[MAXN + 1][25], dep[MAXN + 1];
voidgetFa(int u, int f){ fa[u][0] = f; dep[u] = dep[f] + 1; for (int i = 1; i <= 20; i++) fa[u][i] = fa[ fa[u][i - 1] ][i - 1]; for (int v : e[u]) { if (v == f) continue; getFa(v, u); } }
intlca(int u, int v){ if (dep[u] < dep[v]) std::swap(u, v); for (int i = 20; i >= 0; i--) { if (dep[ fa[u][i] ] >= dep[v] ) { u = fa[u][i]; } } if (u == v) return u; for (int i = 20; i >= 0; i--) { if (fa[u][i] != fa[v][i]) { u = fa[u][i]; v = fa[v][i]; } } return fa[u][0]; }
intmain(){ std::cin >> n; for (int i = 0, x, y; i < n - 1; i++) { scanf("%d%d", &x, &y); e[x].push_back(y); e[y].push_back(x); }
getFa(1, 0);
int q; std::cin >> q; while (q--) { int x, y; scanf("%d%d", &x, &y);