//详解见https://www.cnblogs.com/zwfymqz/p/7795299.html

//博主: 自为风月马前卒 https://www.cnblogs.com/zwfymqz/

// 洛谷 P3379 最近公共祖先 链接https://www.luogu.org/problem/P3379

 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 }
View Code
02-11 22:08