int n, m, s, u, v, pp; constint maxn = 100001, lg = 20; int dep[maxn], p[lg][maxn];
//DFS 预处理 dep 与直接父节点 p[0][u] voiddfs(int u, int fa, const vector<vector<int>> &graph){ p[0][u] = fa; for (int i = 0; i < graph[u].size(); i++) { int v = graph[u][i]; if (v != fa) { dep[v] = dep[u] + 1; dfs(v, u, graph); } } }
//倍增LCA intlca(int u, int v){ if (dep[u] < dep[v]) swap(u, v); // 保证 u 是较深节点 // 将 u 上提到与 v 同深度 for (int k = lg - 1; k >= 0; k--) { if (dep[u] - dep[v] >= (1 << k)) { u = p[k][u]; } } if (u == v) return u; // 同时向上跳,直到 u 和 v 的父节点相同 for (int k = lg - 1; k >= 0; k--) { if (p[k][u] != p[k][v]) { u = p[k][u]; v = p[k][v]; } } return p[0][u]; }
intmain(){ cin >> n >> m >> s; vector<vector<int>> graph(n + 1); for (int i = 0; i < n - 1; i++) { cin >> u >> v; graph[u].push_back(v); graph[v].push_back(u); } dep[s] = 1; // 设置根节点深度为1,避免dep[s]=-1导致的负数 dfs(s, 0, graph);
// 预处理p[k][u] for (int k = 1; k < lg; k++) { for (int i = 1; i <= n; i++) { pp = p[k - 1][i]; if (pp != 0) p[k][i] = p[k - 1][pp]; else p[k][i] = 0; } } // 查询 for (int i = 0; i < m; i++) { cin >> u >> v; cout << lca(u, v) << '\n'; } return0; }