带权并查集
带权并查集
来自4.12蓝桥杯python B组
原题复现:
题目描述
为了提升用户粘性,平台产品经理提出了全新的”圈层互动”功能。系统中共有 个用户结点,初始时,每位用户的”活跃度”均为 ,且彼此之间处于陌生人状态,没有任何社交关联。
随着产品功能的上线,后台日志将按顺序记录 条用户行为指令。这些指令如下:
- 建立好友:用户 与用户 相互关注,双方所在的社交圈正式连通。若两者已处于同一社交圈,则忽略此操作。
- 发布个人动态:用户 发布了一条个人动态,其个人活跃度提升 个单位。
- 圈层热议:用户 发起了一个热门话题,该话题产生极强的辐射效应,使得所有与 处于同一社交圈(即通过好友关系可直接或间接连通)的用户,其活跃度同步追加 个单位。
- 数据查询:运营团队请求获取用户 当前的活跃度数,用于分析用户质量。
随着用户量激增,高频的社交互动请求让服务器核心计算模块面临巨大压力。作为小蓝的协助者,请你接管日志处理单元,并按顺序输出所有的查询结果。
输入格式
第一行包含两个正整数 和 ,分别代表平台用户总数与行为日志的总条数。
随后 行,每行描述一条具体的行为指令,格式遵循以下四种类型之一:
- : 执行"建立好友",连通用户 与 的社交圈。
- : 执行"个人动态",为用户 的活跃度增加 。
- : 执行"圈层热议",为 所在社交圈内的所有用户活跃度增加 。
- : 执行"数据查询",查询用户 的当前活跃度。
输出格式
针对每一条”数据查询”指令,输出单独的一行整数,代表目标用户当前的活跃度数值。
解题报告
并查集的核心思路是以根节点作为元素集合的桥梁.
- 初始化时,每个元素的根节点指向自身,即
parent[x] = x. - 执行操作1”建立好友”时,先判断二者是否有共同根节点,若有,则可直接忽略,若无,则从二者中选取一个作为另一个的父节点,即
parent[Y] = X. - 执行操作3”圈层热议”时,查找
X的父节点并向上遍历,直至找到最终的初始根节点,初始根节点root满足parent[root] = root,然后将所有以root连通的元素加上附加值A.
另建数组user用来存储每个元素通过操作3积累的个人活跃度
简单并查集问题这就够了
然而这题是带权并查集😒
如果按简单的并查集操作几乎必然出现错误,当两个已存在的集合合并时,作为子节点的集合从操作3中积累的活跃度会全部丢失,因此需要另外建立权数组(表示节点相对其父节点的偏移量)weight来记录数据的权值
此题Q,N数据量达到2e5级别,Python实现时需要用sys.stdin.readline()快速读取
代码实现
python
1 | |

.jpg)
.jpg)
.jpg)
.jpg)
.jpg)