先说一下本题思路

  • 1.看清题目,主要有俩个操作,合并和查询 。 总体思路是找到俩个祖宗节点,并且把俩个祖宗节点相连(其实就是改p[a的祖宗]=b的祖宗 比如p[3]=4,p[3]=p[4]=4,他们的祖宗都是4,)

  • 2.合并是在一个数组中,利用下标和他所指向的值,如果他所指向的值一样,那么就是一个集合。用下表来记录具体数据。

  • 3.查询直接查询祖宗节点,很好理解,就是比如说查询x,他就会查询p[x]的值,如果和x不一样,会查询find[p[x]]的值,这里有点绕,x如果和p[x]的值不一样,就查询find(p[x]),一个个找,找到祖宗节点,就是x和p[x]一样的节点,原始节点。

  • 主要操作就是针对于祖宗节点进行的。

  • 题目难点(个人愚见):find函数,寻找祖宗节点的过程,下标和值的用法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>

using namespace std;

const int N = 100010;

int p[N];
int find(int x) //找祖宗节点的函数
{
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}

bool only(int a,int b) //判断是否在一个集合
{
return find(a)==find(b);
}


int main()
{
int a,b;
char str,test;
int n,m;

scanf("%d%d",&n,&m);
scanf("%c",&test); //消除回车

for(int i = 1;i<=n; i++)
p[i]=i;

while(m--)
{

scanf("%c %d %d",&str,&a,&b);
scanf("%c",&test); //消除回车
// printf("%c%d%d\n",str,a,b);
if(str == 'M')
{
p[find(a)]=find(b); //合并操作,
}
else if(str == 'Q')
{
if(only(a,b)) printf("Yes\n");
else printf("No\n");
}

}

return 0;
}