【题意】:求一棵树上的最近公共祖先。

【题解】:模板题。

【代码】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "vector"
 6 #include "queue"
 7 #include "cmath"
 8 #include "string"
 9 #include "cctype"
10 using namespace std;
11 #define pb push_back
12 #define lc(x) (x << 1)
13 #define rc(x) (x << 1 | 1)
14 #define lowbit(x) (x & (-x))
15 #define ll long long
16 #define maxn 10005
17 vector<int> tree[maxn], Q[maxn];
18 int in[maxn], n;
19 bool visit[maxn];
20 int fa[maxn];
21 
22 void init() {
23     for(int i = 0; i <= n; i++) fa[i] = i, tree[i].clear(), Q[i].clear();
24     memset(visit, falsesizeof(visit));
25     memset(in, 0, sizeof(in));
26 }
27 
28 int find(int x) {
29     if(x == fa[x]) return x;
30     else return fa[x] = find(fa[x]);
31 }
32 
33 bool un(int a, int b) {
34     a = find(a), b = find(b);
35     if(a == b) return false;
36     fa[b] = a;
37     return true;
38 }
39 
40 void Tarjan(int u) {
41     int size = tree[u].size();
42     for(int i = 0; i < size; i++) {
43         Tarjan(tree[u][i]);
44         un(u, tree[u][i]);
45     }
46     visit[u] = true, size = Q[u].size();
47     for(int i = 0; i < size; i++) {
48         if(visit[Q[u][i]]) {
49             printf("%d\n", find(Q[u][i]));
50             return;
51         }
52     }
53 }
54 
55 int main() {
56     int T, u, v;
57     scanf("%d", &T);
58     while(T--) {
59         scanf("%d", &n);
60         init();
61         for(int i = 0; i < n - 1; i++) {
62             scanf("%d%d", &u, &v);
63             tree[u].pb(v);
64             in[v]++;
65         }
66         scanf("%d%d", &u, &v);
67         Q[u].pb(v), Q[v].pb(u);
68         int root = -1;
69         for(int i = 1; i <= n; i++) {
70             if(in[i] == 0) {
71                 root = i;
72                 break;
73             }
74         }
75         Tarjan(root);
76     }
77     return 0;
78 }
79