“景驰科技杯”2018年华南理工大学程序设计竞赛 B. 一级棒!(并查集)

题目链接:https://www.nowcoder.com/acm/contest/94/B

题意:在一棵有 n 个节点的树上,有两种操作,一个是把 u 到 v 的路径走一遍,另一个是查询 u 到 fa[ u ]的路径走了几次,如果没走过输出“ Not yet ”,走过一次升序输出经过要走这条路时的路径端点,否则输出“ Many Times”。

题解:因为只需记录每条路径经过一次,若一条路径经过了多次,则访问该节点时可跳到它的没有访问过路径的祖先上面,故可以使用并查集来实现。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define mst(a,b) memset((a),(b),sizeof(a))
 5 #define pi acos(-1)
 6 #define pii pair<int,int>
 7 const int INF = 0x3f3f3f3f;
 8 const double eps = 1e-3;
 9 const int MAXN = 1e5 + 10;
10 const int MAXM = 2e6 + 10;
11 const ll mod = 1e9 + 7;
12  
13 int n;
14 int num[MAXN],fa[MAXN],pre[MAXN],dep[MAXN];
15 int ansl[MAXN],ansr[MAXN];
16  
17 int findd(int x) {
18     if(pre[x] == x) return x;
19     return pre[x] = findd(pre[x]);
20 }
21  
22 void update(int u,int v) {
23     int a = u, b = v;
24     while(u != v) {
25         if(dep[u] < dep[v]) swap(u,v);
26         num[u]++;
27         if(num[u] == 1)
28             ansl[u] = min(a,b),ansr[u] = max(a,b);
29         else
30             pre[u] = fa[u];
31         u = findd(fa[u]);
32     }
33 }
34  
35 int main()
36 {
37 #ifdef local
38     freopen("data.txt","r",stdin);
39 //    freopen("data.txt","w",stdout);
40 #endif
41     while(~scanf("%d",&n)) {
42         mst(num,0);
43         for(int i=1; i<n; i++) {
44             int x;
45             scanf("%d",&x);
46             fa[i] = x;
47             pre[i] = i;
48             dep[i] = dep[x] + 1;
49         }
50         int q;
51         scanf("%d",&q);
52         while(q--) {
53             char s[5];
54             scanf("%s",s);
55             if(s[0] == 'R') {
56                 int u,v;
57                 scanf("%d%d",&u,&v);
58                 update(u,v);
59             }
60             else {
61                 int u;
62                 scanf("%d",&u);
63                 if(num[u] == 0) puts("Not yet");
64                 else if(num[u] == 1) printf("%d %d
",ansl[u],ansr[u]);
65                 else puts("Many times");
66             }
67         }
68     }
69     return 0;
70 }
原文地址:https://www.cnblogs.com/scaulok/p/9770592.html