题目描述
如题,现在有一个并查集,你需要完成合并和查询操作。
输入格式
第一行包含两个整数 N,M ,表示共有 N 个元素和 M 个操作。
接下来 M 行,每行包含三个整数 Zi,Xi,Yi 。
当 Zi=1 时,将Xi 与 Yi 所在的集合合并。
当 Zi=2 时,输出Xi 与 Yi 是否在同一集合内,是的输出 Y
;否则输出 N
。
输出格式
对于每一个Zi=2 的操作,都有一行输出,每行包含一个大写字母,为 Y
或者 N
。
输入输出样例
输入 #1复制
4 7 2 1 2 1 1 2 2 1 2 1 3 4 2 1 4 1 2 3 2 1 4
输出 #1复制
N Y N Y
说明/提示
对于 30%30% 的数据,N≤10,M≤20。
对于 70%70% 的数据,N≤100,M≤103。
对于 100%100% 的数据,1≤N≤10e4,1≤M≤2×10e5,1≤Xi,Yi≤N,Zi∈{1,2}Zi∈{1,2}。
思路
采用并查集的思想,并查集可以解决的问题是,1.查询两个集合是否属于一个集合,2.将两个集合合并成一个集合。可以采用树的思想来理解问题,首先开始之前将每一个数看成一棵树。当其他数与其组成集合时,就是将这个节点与其相连。1.当问到是否属于一个集合时就是查询一下这两棵树的根节点是否一样,2当要合并这两个集合时也是将一个集合的根节点搭在另一个集合的根节点上,相当于画一条线。
重要思想:
1.p[当前节点]=父节点
2.由于两种操作中我们始终关注的时根节点,故可以采用路径压缩,直接p[当前节点]=根节点
3.根节点的父节点为其本身
4.代码实现,采用数组来实现
代码:
def find(x):
#根据树的结构一步步往上找根节点
if p[x]!=x:#判断p现在指向的值是否是根节点
p[x]=find(p[x])#找到根节点赋值给p[当前节点]指向的值,一步步递归找,p[x]指向的是其父节点,find函数查找其父节点,
return p[x]#返回根节点
N,M=map(int,input().split())#输入N个元素和M个操作
#输入n个数开始的时候自己成一个集合,即p[当前节点]=当前节点,是p[1]=1,p[2]=2,p[3]=3,p[4]=4.....
p=[i for i in range(N+1)]
#开始进行M个操作
for i in range(M):
op=input().split()#由于Python是弱类型语言故可以这样赋值
a,b=int(op[1]),int(op[2])
if op[0]=='1':
#进行合并
#将根节点搭在一起,即p[当前节点]=父节点
p[find(a)]=find(b)#p[find(a)]即是p[a的父节点,找到根节点]=find(b)找到b的根节点,连接两个集合
else:
#查询是否在同一个集合,即查询根节点是否是同一个
if find(a)==find(b):
print('Y')
else:
print('N')