算法基础:并查集详解

并查集

并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内赛题中。其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受;即使在空间上勉强通过,运行的时间复杂度也极高,根本就不可能在比赛规定的运行时间(1~3秒)内计算出试题需要的结果,只能用并查集来描述。

以上释义来自:百度百科

并查集是一种树型的数据结构,用于处理一些不相交集合(disjoint sets)的合并及查询问题


  • 根节点的编号就代表该集合的编号
  • 树中每一个节点存储着它的父亲节点
基本原理
  • 如何判断树根
if(p[x]==x)
  • 如何求X的集合编号
while(p[x]!=x) x = p[x];
  • 如何合并两个集合(本质上就是合并两棵树)

方法:将集合1或者2插入到集合1或者2的某个位置即可【根节点之下的某个位置】

** 设Px是x的集合编号,Py是y的集合编号,则合并操作**:p[x] = y;


画解合并/插入

初始时每个集合都是一个独立的集合且集合的编号等于自己下标数。
:)例:p[2]=2,p[6]=6将两个集合进行合并

  • 1.找到p[2]【该集合的根就是该集合的编号】集合的父节点
  • 2.找到p[6]集合父亲节点
  • 3.p[2]集合的父节点指向p[6]集合即可。
    合并后:p[2] = p[6] = 6;
    因为p[2]=2,p[6]=6
    所以合并后的集合{6,2},一个以6为祖宗节点的集合

插入

将以p[6]为根的集合{4,7,10}插入到以p[5]为根的集合{5,3,9}
显然p[3]=5,p[9]=5,p[5]=5p[4]=6,p[7]=6,p[10]=6,p[6]=6
那么只要找到集合p[6]中的祖宗节点【6】指向集合p[5]即可【不一定直接作为其第一个儿子,指向其孙子【比如指向p[3]】也是可以的,因为p[3]的父亲也是5】。
所以有:p[6] = find(3) or p[6] = find(9)【find(x)为寻找x节点的祖宗节点】


路径压缩

可以看到,在计算x的集合编号的时候还是比较耗时的,所以介入了一个优化算法 【路径压缩】

由于每次都要将x指向它的父亲节点,x = p[x]
因此只要搜索一次成功后将该路径上所有的节点x都指向其祖宗节点。这样再一次查询之后,之后的每一次都是近乎O(1)的操作了

这也是并查集NB的一个地方。

代码模板
 int p[N]; //存储每个点的祖宗节点
    // 返回x的祖宗节点
    int find(int x)
    {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }

    // 初始化,假定节点编号是1~n
    for (int i = 1; i <= n; i ++ ) p[i] = i;

    // 合并a和b所在的两个集合:
    p[find(a)] = find(b);
模板练习


// Problem: 合并集合
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/description/838/
// Memory Limit: 64 MB
// Time Limit: 1000 ms

#include<iostream>
#include<algorithm>
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];

}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		p[i] = i;
	}	
	while(m--)
	{
		char op[2];
		int a,b;
		scanf("%s%d%d",op,&a,&b);
		//合并集合
		if(*op=='M') p[find(a)]=find(b);
		else if(find(a)==find(b))
		printf("Yes\n");
		else
		printf("No\n");
	}
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Web前端开发之HTML_2

HTML5简介与基础骨架标题标签标签之段落、换行、水平线标签之图片标签之超文本链接标签之文本列表标签之有序列表列表标签之无序列表 1. HTML5简介与基础骨架 1.1 HTML5简介 HTML5是用来描述网页的一种语言&#xff0c;被称为超文本标记语言。用HTML5编写的文件&#xff0c;后…

伴游平台搭建重点,会用到哪些三方服务?

伴游平台搭建的重点在于确保用户的安全与体验&#xff0c;提供便捷的服务&#xff0c;同时维护平台的稳定运营。在搭建过程中&#xff0c;可能会用到以下三方服务&#xff1a; 身份验证与背景调查服务&#xff1a;由于伴游服务涉及到用户的个人安全和信任问题&#xff0c;因此需…

企业微信代开发应用登录操作

首先声明&#xff1a;企微的文档写得真烂&#xff01;&#xff01;&#xff01;有一些问题&#xff0c;官方情愿在问答区给用户一个个解答&#xff0c;也不愿意在文档写清楚&#xff0c;生怕自己工作量不饱和被优化。 概念说明 代开发应用&#xff0c;是相对于自建应用来说的。…

如何解决 IntelliJ IDEA 2024 启动总闪退问题?一站式解决方案!

&#x1f9e0; 如何解决 IntelliJ IDEA 2024 启动总闪退问题&#xff1f;一站式解决方案&#xff01; 文章目录 &#x1f9e0; 如何解决 IntelliJ IDEA 2024 启动总闪退问题&#xff1f;一站式解决方案&#xff01;摘要引言正文一级标题&#xff1a;检查和优化内存设置一级标题…

经验丰富也被裁了,失业快2年找不到工作?

前几天徐工说&#xff0c;他有个邻居&#xff0c;最近逮到他总是要跟他扯上几句。 原因是徐工一直是做嵌入式开发&#xff0c;而他一直做纯软件开发&#xff0c;具体不知道做后端还是前端。 他说&#xff0c;他至少有半年没上班了&#xff0c;之前在一家龙头物流公司上班。 碰上…

五年Python从业者,谈谈Python的一些优缺点

前言 Python它是作为年轻的血液&#xff0c;融入到编程语言这个大家庭里面&#xff0c;作为具有年轻人的蓬勃朝气的python&#xff0c;那它同时就会有年轻人的桀骜焦躁。 今天就来谈谈Python的一些优缺点。 先从优点说起&#xff0c;我是把它分为5部分。 1.简单————Pyth…

2024最新版JavaScript逆向爬虫教程-------基础篇之深入JavaScript运行原理以及内存管理

目录 一、JavaScript运行原理1.1 前端需要掌握的三大技术1.2 为什么要学习JavaScript1.3 浏览器的工作原理1.4 浏览器的内核1.5 浏览器渲染过程1.6 认识JavaScript引擎1.7 V8引擎以及JavaScript的执行过程1.8 V8引擎执行过程 二、JavaScript的执行过程2.1 初始化全局对象2.2 执…

【vue功能】多张图片合并

多张图片合并成一张图片 步骤一&#xff0c;多张图片上传步骤二&#xff0c;循环获取所有绘制图片的总高度new FileReader()方法作用new Image()方法作用介绍 步骤三&#xff0c;合并多张图片canvas.toDataURL()作用-dpr作用 步骤四&#xff0c;下载图片 步骤一&#xff0c;多张…

深入Linux下的GCC编译器:从入门到精通

目录标题 1、GCC编译器概述2、安装GCC3、GCC的基本使用4、高级功能4.1 多文件编译4.2 静态和动态链接4.3 什么是链接&#xff1f;4.4 静态链接优点缺点 4.5 动态链接优点缺点 4.6 实际应用4.7 编译优化 GCC&#xff08;GNU Compiler Collection&#xff09;是一款免费、开源的编…

从 Android 恢复已删除文件的 3 种简单方法

如何从 Android 恢复已删除的文件&#xff1f;毫不犹豫&#xff0c;有些人可能会认为从 Google 备份恢复 Android 文件太容易了。但是&#xff0c;如果删除的文件未同步到您的帐户或未备份怎么办&#xff1f;您错误的恢复可能会永久删除您想要的数据。因此&#xff0c;我们发布…

Maven 安装及配置教程(Windows)【安装】

文章目录 一、 下载1. 官网下载2. 其它渠道 二、 安装三、 配置四、 验证五、 本地仓储配置六、 配置镜像七、 配置JDK八、完整配置九、常用命令十、IDEA 中配置 Maven1. 配置当前项目2. 配置新建 / 新打开 项目 软件 / 环境安装及配置目录 一、 下载 1. 官网下载 安装地址&a…

【2024年最新】NodeMCU-ESP8266刷AT固件教程——适用于esp-12E和esp-12F

硬件图片 原理图 0、工具打包下载 工具包 密码:keduo 1、工具及固件下载 固件下载地址&#xff1a; 欢迎 | 安信可科技 (ai-thinker.com) 下载以下固件&#xff1a; 直接下载地址&#xff1a;AT 固件&#xff08;固件号&#xff1a;0781&#xff09; 下载以下工具&#xf…

【前端】vue数组去重的3种方法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、数组去重说明二、Vue数组去重的3种方法 前言 随着开发语言及人工智能工具的普及&#xff0c;使得越来越多的人会主动学习使用一些开发工具&#xff0c;本文…

react09 hooks(useState)

react-09 hooks&#xff08;useState&#xff09; hooks组件&#xff08;函数组件动态化&#xff09; 其本质就是函数组件&#xff0c;引用一些hooks方法&#xff0c;用来在函数组件中进行例如状态管理&#xff0c;模拟类组件的生命周期等&#xff0c;只能运用到函数组件中 ho…

基于MaxKB搭建一个知识库问答系统

什么是MaxKB MaxKB 是一款基于 LLM 大语言模型的知识库问答系统。MaxKB Max Knowledge Base&#xff0c;旨在成为企业的最强大脑。 开箱即用&#xff1a;支持直接上传文档、自动爬取在线文档&#xff0c;支持文本自动拆分、向量化&#xff0c;智能问答交互体验好&#xff1b…

DHCP Relay配置与抓包

前言&#xff1a;DHCP请求报文是以广播包方式发送的&#xff0c;当DHCP服务器与DHCP客户端不在同一网段时&#xff0c;就需要在三层网关设备配置DHCP中继功能 。 为能更好理解DHCP Relay功能&#xff0c;建议先看看DHCP Server的内容 https://blog.csdn.net/weixin_58574637…

【Java框架】SpringMVC(三)——异常处理,拦截器,文件上传,SSM整合

目录 异常处理解释局部异常处理全局异常 拦截器拦截器介绍作用:拦截器和过滤器之间的区别拦截器执行流程代码实现补充 文件上传依赖配置MultipartResolver编写文件上传表单页APIMultipartFileFile.separator必须对上传文件进行重命名代码示例 SpringMVC文件上传流程多文件上传 …

你知道吗?PCBA产品上市前还需要进行老化测试?

在PCBA加工过程中&#xff0c;电子工程师可能发现明明PCBA板出货时各项功能指标正常&#xff0c;但使用一段时间&#xff0c;就莫名其妙出现各种不良问题&#xff0c;最后返场维修&#xff0c;那么这是为什么&#xff1f; 首先&#xff0c;这些原因&#xff0c;十有八九可能是P…

谷歌开发者账号关联被封?解封申诉指南来了!

相信大部分在谷歌上架应用的开发者&#xff0c;已经被谷歌封号封麻了。且不少开发者普遍认为&#xff0c;一旦开发者账号被封禁&#xff0c;想要成功申诉回来的难度极大。 特别是那些因为涉及“高风险”滥用模式行为关联被封的账号&#xff0c;更是不可能申诉成功。但事实上&am…

再谈C语言——理解指针(五)(完结篇)

数组名的理解 在上⼀个章节我们在使⽤指针访问数组的内容时&#xff0c;有这样的代码&#xff1a; int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0]; 这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址&#xff0c;但是其实数组名本来就是地址&#xf…