Detailed // See https://www.cnblogs.com/zwfymqz/p/7795299.html
// blogger: from love affair to pawn https://www.cnblogs.com/zwfymqz/
// Los Valley P3379 recent common ancestor link https://www.luogu.org/problem/P3379
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 const int MAXN = 1e5+10; 7 8 struct node { 9 int v, next; 10 } edge[MAXN]; 11 12 int head[MAXN]; 13 int num = 1; 14 inline void add_edge(int x, int y) { 15 edge[num].v = y; 16 edge[num].next = head[x]; 17 head[x] = num++; 18 } 19 20 int f[MAXN][21]; 21 int deep[MAXN]; 22 int n, m, root; 23 void dfs(int cur) { 24 for(int i = head[cur]; i != -1; i = edge[i].next) { 25 if(!deep[edge[i].v]) { 26 deep[edge[i].v] = deep[cur] + 1; 27 f[edge[i].v][0] = cur; 28 dfs(edge[i].v); 29 } 30 } 31 } 32 33 void PRE() { 34 for(int j = 1; j <= 19; ++j) { 35 for(int i = 1; i <= n; ++i) { 36 f[i][j] = f[f[i][j-1]][j-1]; 37 } 38 } 39 } 40 41 int LCA(int x, int y) { 42 if(deep[x] < deep[y]) swap(x, y); 43 for(int i = 19; i >= 0; --i) { 44 if(deep[f[x][i]] >= deep[y]) { 45 x = f[x][i]; 46 } 47 } 48 if(x == y) return x; 49 for(int i = 19; i >= 0; --i) { 50 if(f[x][i] != f[y][i]) { 51 x = f[x][i]; 52 y = f[y][i]; 53 } 54 } 55 return f[x][0]; 56 } 57 58 int main() { 59 memset(head, -1, sizeof(head)); 60 scanf("%d%d%d", &n, &m, &root); 61 int x, y; 62 for(int i = 0; i != n-1; ++i) { 63 scanf("%d%d", &x, &y); 64 add_edge(x, y); 65 add_edge(y, x); 66 } 67 deep[root] = 1; 68 dfs(root); 69 PRE(); 70 for(int i = 0; i != n; ++i) { 71 scanf("%d%d", &x, &y); 72 printf("%d\n", LCA(x, y)); 73 } 74 return 0 ? 75 }