【StarryCoding P9】【模板】可撤销并查集(并查集+启发式合并+栈)

描述

给定 n n n个结点, q q q次询问,每次询问分为三类:

  1. 1 x y :可以选择将 x , y x, y x,y两个点连通,如果已经连通则不操作。
  2. 2 :撤销上一次的操作(若全部撤销完了则不操作)。
  3. 3 x y:询问 x , y x, y x,y是否连通,如果是则输出"YES",反之输出"NO",请注意都是大写字母,不包含引号。

输入描述

第一行两个整数 n ( 1 ≤ n ≤ 1 0 6 ) , q ( 1 ≤ q ≤ 1 0 5 ) n (1 \leq n \leq 10^6), q (1 \leq q \leq 10^5) n(1n106),q(1q105),分别表示结点的个数和询问的次数。

接下来 q q q行,每行一个询问op x y (1 \leq op \leq 3, 1 \leq x, y \leq n),当op=2时,没有 x , y x, y x,y

输出描述

对于每一个3询问,一行一个字符串(“YES” 或 “NO”)表示结果。

输入样例1

4 5
1 1 2
1 1 3
3 2 3
2
3 2 3

输出样例1

YES
NO

思路

在初始化函数init中,遍历每个元素,将其父节点设置为自己,表示每个元素都是独立的集合,同时集合的大小设置为1。

函数root负责查找元素的根节点。通过不断向上查找父节点,直到找到一个元素的父节点是其自身,即找到了该元素所在集合的根节点。

函数merge负责合并两个集合。首先查找两个元素的根节点,如果根节点相同,表示两个元素已经在同一集合中,无需合并。否则,将较小的集合并入较大的集合,为了保证并查集的平衡性,这里使用了按秩合并的策略。在合并的同时,将合并的信息(较小集合的根节点和较大集合的根节点)压入栈s1,以便后续进行撤销操作。

函数check负责检查两个元素是否在同一集合中。通过查找两个元素的根节点,如果根节点相同,表示两个元素在同一集合中,输出"YES";否则,表示两个元素不在同一集合中,输出"NO"。

函数undo负责撤销最近的合并操作。从栈s1中弹出最近的合并信息,将被合并的集合的根节点的父节点设置为其自身,同时更新其父节点(即原集合)的大小,恢复原来的集合状态。

在主函数中,首先读取元素个数和操作次数,然后进行初始化。然后根据操作类型进行相应的操作,如果操作类型为2,则进行撤销操作;如果操作类型为1,则进行合并操作;如果操作类型为3,则进行检查操作。


AC代码

#include <algorithm>
#include <iostream>
#include <stack>
#define AUTHOR "HEX9CF"
using namespace std;const int N = 1e5 + 7;int pre[N], sz[N];
stack<pair<int, int>> s1;void init(int x) {for (int i = 1; i <= x; i++) {pre[i] = i;sz[i] = 1;}
}int root(int x) {int i = x;while (pre[i] ^ i) {i = pre[i];}return i;
}void merge(int x, int y) {int rx = root(x);int ry = root(y);if (rx == ry) {return;}if (sz[rx] > sz[ry]) {swap(rx, ry);}s1.push({rx, ry});pre[rx] = ry;sz[ry] += sz[rx];
}void check(int x, int y) {int rx = root(x);int ry = root(y);if (rx == ry) {printf("YES\n");} else {printf("NO\n");}
}void undo() {if (s1.empty()) {return;}auto t = s1.top();s1.pop();int rx = t.first;int ry = t.second;pre[rx] = rx;sz[ry] -= sz[rx];
}int main() {int n, m;scanf("%d %d", &n, &m);init(n);while (m--) {int opt;scanf("%d", &opt);if (opt == 2) {undo();} else {int a, b;scanf("%d %d", &a, &b);if (opt == 1) {merge(a, b);} else {check(a, b);}}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/686525.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flex布局简介及微信小程序视图层View详解

目录 一、Flex布局简介 什么是flex布局&#xff1f; flex属性 基本语法和常用属性 Flex 布局技巧 二、视图层View View简介 微信小程序View视图层 WXML 数据绑定 列表渲染 条件渲染 模板 WXSS 样式导入 内联样式 选择器 全局样式与局部样式 WXS 示例 注意事项…

with ThreadPoolExecutor() as executor的使用举例

ThreadPoolExecutor是Python的concurrent.futures模块中的一个类&#xff0c;用于创建一个线程池执行器&#xff0c;可以并发地执行多个任务。 下面是一个使用ThreadPoolExecutor的示例&#xff1a; python from concurrent.futures import ThreadPoolExecutor # 定义一个需…

软件测试概论

第一章、认识软件 一、概述 软件又叫做软体&#xff0c;英文是software 不同的设备上叫法不一样 普通的

【Linux系统化学习】文件重定向

目录 文件内核对象 文件描述符的分配规则 重定向 重定向的概念 dup2系统调用 输出重定向 追加重定向 输入重定向 stderr解析 重定向到同一个文件中 分离常规输出和错输出 文件内核对象 上篇文章中我们介绍到了操作系统中的文件&#xff0c;操作系统为了方…

不同类型的网络拓扑结构在不同的应用场景和需求

不同类型的网络拓扑结构适用于不同的应用场景和需求&#xff0c;下面简要概括几种常见拓扑结构的使用场景及特点&#xff1a; 1、星形 • 使用场景 广泛应用于家庭网络、办公室局域网、企业内部网络以及许多无线网络如Wi-Fi。 • 特点与需求 每个设备通过一条单独的链路连接…

Shellcode免杀对抗(C/C++)

Shellcode C/C免杀&#xff0c;绕过360安全卫士、火绒安全、Defender C/C基于cs/msf的上线 首先是测试一下shellcode上线&#xff0c;主要是俩种方法 测试环境 攻击机&#xff1a;kali2023 靶机&#xff1a;win10 msf方法 首先是启动msf msfconsole 然后msf生成一个sh…

CES 2024:NVIDIA 通过新的笔记本电脑、GPU 和工具提供生成式 AI

在 CES 2024 上&#xff0c;NVIDIA 推出了一系列硬件和软件&#xff0c;旨在释放 Windows 11 PC 上生成式 AI 的全部潜力。 在 PC 上本地运行生成式 AI 对于隐私、延迟和成本敏感型应用程序至关重要。在 CES 上&#xff0c;NVIDIA 将在整个技术堆栈中带来新的创新&#xff0c;…

bat 定时收缩sqlserver2012

在Windows环境下&#xff0c;你可以使用任务计划程序&#xff08;Task Scheduler&#xff09;来定时执行批处理文件&#xff0c;进而收缩SQL Server 2012的数据库。批处理文件&#xff08;.bat&#xff09;将包含执行收缩操作的SQL命令。然而&#xff0c;如前所述&#xff0c;定…

C#开源免费的Windows右键菜单管理工具

前言 今天分享一个C#开源、免费、纯粹的Windows右键菜单管理工具&#xff1a;ContextMenuManager。 工具主要功能 程序支持国际化多语言显示。启用或禁用文件、文件夹、新建、发送到、打开方式、自定义文件格式、IE浏览器、WinX等右键菜单项目。对上述场景右键菜单项目进行修…

MySql查询中按多个字段排序的方法

目录 前言 一、按单个字段排序&#xff1a; 二、按多个字段排序&#xff1a; 二、指定排序方向&#xff1a; 总结 前言 在 SQL 查询中&#xff0c;经常需要按多个字段对结果进行排序。本文将介绍如何使用 SQL 查询语句按多个字段进行排序&#xff0c;提供几种常见的排序方…

【NI-DAQmx入门】数据采集中的降噪技术

1.什么是噪声&#xff1f; 噪声是电路中存在的与期望信号不同的任何电信号 噪声可以降低&#xff0c;但不能消除 噪声可以在源头处被抑制 通过耦合可以降低数据传输通道的噪声 2.噪声耦合方法 导电性 电容性 感应性 其他 3.传导耦合噪声 来自不同电路的电流在一个公共阻抗中共…

⭐北邮复试刷题103. 二叉树的锯齿形层序遍历

103. 二叉树的锯齿形层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff1a;输入&#xff1a…

英文论文(sci)解读复现【NO.21】一种基于空间坐标的轻量级目标检测器无人机航空图像的自注意

此前出了目标检测算法改进专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读发表高水平学术期刊中的 SCI论文&a…

代码随想录day27 Java版

122.买卖股票的最佳时机 II 简单题&#xff0c;每天都贪心即可 class Solution {public int maxProfit(int[] prices) {int sum 0;for (int i 1; i < prices.length; i) sum Math.max(prices[i]-prices[i-1],0);return sum;} } 55. 跳跃游戏 记录能跳的最远范围&…

告警能力中台设计与实践(二)——事件树系统

一、现有告警平台分析 在设计核心的告警数据模型时&#xff0c;本质上是对业务逻辑与整理数据流的梳理与设计。对于这部分不可高屋建瓴、想当然&#xff0c;需要有成熟的 取其精华、根据自身业务需求再做优化与改进才是正道。 笔者所在的部门SRE平台恰巧已有相关告警能力&…

AutoKeras(Python自动化机器学习)多模态数据和多任务

要点拓扑 AutoKeras 拓扑 要点 常规机器学习&#xff1a;scikit-learn示例探索性数据分析和数据预处理&#xff0c;线性回归&#xff0c;决策树图像分类ResNet模型示例&#xff0c;合成数据集DenseNet模型示例绘图线性回归和决策树模型使用Python工具seaborn、matplotlib、pan…

论文阅读:四足机器人对抗运动先验学习稳健和敏捷的行走

论文&#xff1a;Learning Robust and Agile Legged Locomotion Using Adversarial Motion Priors 进一步学习&#xff1a;AMP&#xff0c;baseline方法&#xff0c;TO 摘要&#xff1a; 介绍了一种新颖的系统&#xff0c;通过使用对抗性运动先验 (AMP) 使四足机器人在复杂地…

Github项目推荐-Tiny-Rdm

项目地址 GitHub - tiny-craft/tiny-rdm: A Modern Redis GUI Client 项目简述 一个开源的Redis管理工具&#xff0c;有漂亮的界面和丰富的功能。使用的编程语言如下 项目截图

【IIS中绑定SSL证书】

下载SSL证书&#xff1a; 打开服务器IIS&#xff1a; 点击导入 在IIS中新增网站&#xff1a;

【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱8(附带项目源码)

效果演示 文章目录 效果演示系列目录前言砍树功能源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第25篇中&#xff0c;我们将探索如何用unity制作一个3D背包、库存、制作、快捷栏、存…