思路:
纯粹的树上倍增求LCA
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<vector> #include<cstdlib> #include<algorithm> using namespace std; const int maxn = 100010; inline void qread(int &x){ x = 0; register int ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9'){ x = 10 * x + ch - 48; ch = getchar(); } } int n, Q; int deep[maxn]; int llog[maxn]; int f[maxn][25]; vector<int> G[maxn]; void dfs(int x){ for(int i=0; i<G[x].size(); ++i){ if(!deep[G[x][i]]){ f[G[x][i]][0] = x; deep[G[x][i]] = deep[x] + 1; dfs(G[x][i]); } } } int main(void) { srand(19749); qread(n); for(int i=2; i<=n; ++i) llog[i] = llog[i>>1] + 1; for(int i=1; i<n; ++i){ int x, y; qread(x); qread(y); G[x].push_back(y); G[y].push_back(x); } int rt = rand() % n + 1; deep[rt] = 1; dfs(rt); for(int j=1; j<=llog[n]; ++j) for(int i=1; i <= n; ++i) f[i][j] = f[f[i][j-1]][j-1]; qread(Q); while(Q--){ int x, y, ans = 0; qread(x), qread(y); if(deep[x] < deep[y]) swap(x, y); for(int k = llog[n]; k >= 0; k--){ if(deep[f[x][k]] >= deep[y]){ ans += (1 << k); x = f[x][k]; } } if(x != y){ for(int k = llog[n]; k>=0; k--){ if(f[x][k]!= f[y][k]){ ans += (1 << k) << 1; x = f[x][k]; y = f[y][k]; } } ans += 2; } printf("%d\n", ans); } }