【题意】:求一棵树上的最近公共祖先。
【题解】:模板题。
【代码】:
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, false, sizeof(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