P3367 【模板】并查集

文章讲述了在Python中使用并查集解决集合操作问题的方法,涉及路径压缩策略,适用于N个元素和M个操作的场景。
摘要由CSDN通过智能技术生成

题目描述

如题,现在有一个并查集,你需要完成合并和查询操作。

输入格式

第一行包含两个整数 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')

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值