1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| #include<bits/stdc++.h> #define endl '\n' using i64 = long long; using namespace std; signed main(){ std::ios::sync_with_stdio(false);cin.tie(0); int n, m, s; cin >> n >> m >> s; vector<vector<int>> e(n + 1); vector<vector<int>> fa(n + 1, vector<int>(30)); //fa[u][i]表示以u为根结点,往上2^i层次的父亲编号 vector<int>dep(n + 1); for (int i = 1; i < n;i++){ int u, v; cin >> u >> v; e[u].emplace_back(v); e[v].emplace_back(u); } auto dfs = [&](auto dfs, int u, int f, int depth) -> void { if(u!=s){ fa[u][0] = f; for (int i = 1; (1 << i) <= depth;i++) //预处理各父亲结点的编号 fa[u][i] = fa[fa[u][i - 1]][i - 1]; } dep[u] = depth; for(auto it:e[u]) if(it!=f) dfs(dfs, it, u, depth + 1); }; auto lca = [&](int x, int y) -> int { if(dep[x]!=dep[y]){ //使x与y跳到同一高度 if (dep[x] < dep[y]) swap(x, y); int dis = dep[x] - dep[y]; int cur = x; for (int i = 20; i >= 0; i--) if (dis >= (1 << i)) cur = fa[cur][i], dis -= 1 << i; x = cur; } if(x==y) return x; for (int i = 20; i >= 0;i--) if (dep[x] >= (1 << i) && fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i]; return fa[x][0]; }; dfs(dfs, s, -1, 0); while(m--){ int u, v; cin >> u >> v; cout << lca(u, v) << endl; } return 0; }
|