并查集的来龙去脉

【数据结构】【王道408】——从PPT到思维导图:高效掌握并查集与红黑树 本文针对王道408数据结构备考,提出结合PPT截图与思维导图的高效学习方法。以并查集和红黑树为例,详细拆解了从素材整理、知识体系构建到实战应用的完整流程,帮助考生将抽象知识点可视化、结构化,从而深度掌握核心概念与操作,提升复习与解题效率。 阅读详情

1 并查集的思想:

    已知:

     1)很多个元素有着一个属性值,这些属性与其他元素的属性值或相同或不相同;

     2)我们不知道每个元素的属性值,但知道一些两个元素之间属性值相等的关系——等价关系(有自反性,对称性,传递性);

  目标:

      根据等价关系将所有元素划分到对应的等价类中去,每个等价类中的元素两两之间都存在着等价关系。

     算法:

     1)将所有的元素初始化为独立的集合;

     2)根据元素间的等价关系,将对应的元素所在的集合合并Union操作。如何合并?我们给每个集合自定义一个集合值来表示这个集合。Union所需的操作即把原来两个分开的集合的两个集合值改为一个相同的集合值。我们已知等价关系中的两个元素,需要一个Find方法来查询这两个元素对应的集合值,再将这两个集合值修改为一个值;


2.实现:

     并查集是可用树来实现,其实也可以其他的实现方法。比如:

    1).可用额外一个标记数组来表示集合的集合值,而不用代表元素来表示属性。当然,那样Union的复杂度会大大提高O(n),但find的复杂度会降低O(1);

     2).可用多个vector来表示不同的集合。集合的合并的实现为:建立新的vector将原来两个vector的元素都拷贝过来。然后销毁原来的两个vector。那么集合值就是vector的地址。这种理解最直观。无疑,这种方法的效率最低。Union和find的复杂度都为O(n);

      3)用树来实现集合(这也是集合的最常见的实现数据结构)。则可用树的根节点来表示集合值。这样Union操作大大的简化了,只需让一个集合的根节点指向另一个集合的根节点即可——O(1)。当然,find的复杂则达到了近似O(log2 n)。

  树的实现是最理想的。树只是一种逻辑结构,出于方便。我用了STL的关联数组来实现。

class UnionFindSet
{
	public:
		string find(string str);
		bool  unite(string str1,string str2);
		void initial(string str1);
	private:
		map<string,string> _union_find_set;
};

void UnionFindSet::initial(string str1)
{
	_union_find_set[str1]=string("-1");
}

string UnionFindSet::find(string str)
{
	string father=str;
	do{
		str=father;
		father=_union_find_set[str];
	}while(father[0]!='-'&&!father.empty());
	if(father.empty())
		initial(str);
	return str;
}

bool UnionFindSet::unite(string ancestor1,string ancestor2)
{
	int size1,size2;
	if(ancestor1==ancestor2)
		return false;
	else{
		//C++11 is not support in gcc 4.6
		//size1=stoi(_union_find_set[ancestor1]);
		//size2=stoi(_union_find_set[ancestor2]);
		size1=atoi(_union_find_set[ancestor1].c_str());
		size2=atoi(_union_find_set[ancestor2].c_str());
		if(size1>=size2){
			_union_find_set[ancestor1]=ancestor2;

			stringstream ss;
			ss<<size1+size2;
			_union_find_set[ancestor2]=ss.str();
		}
		else{
			_union_find_set[ancestor2]=ancestor1;

			stringstream ss;
			ss<<size1+size2;
			_union_find_set[ancestor1]=ss.str();
		}
		return true;
	}
}


3.应用

 可用并查集来解决很多问题。Kruskal算法,判断图是否含有环。这两个问题的算法都需要归并不同的联通分量。与并查集用于归并集合的用途吻合。


还可用并查集来处理二分图问题。这个问题其实就是判断图是否有包含奇数个节点的环的问题。代码如下,需要添加一个bCircleNodeNumOdd方法:


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//#include <ext/map>
#include <map>
#include <string>
#include <iostream>
#include <sstream>

using namespace std;
//using namespace __gnu_cxx;

class UnionFindSet
{
	public:
		string find(string str);
		bool  unite(string str1,string str2);
		void initial(string str1);
		bool bCircleNodeNum(string str1,string str2);
	private:
		map<string,string> _union_find_set;
};

bool UnionFindSet::bCircleNodeNumOdd(string str1,str2)
{
	//Todo
	return true;
	return false;
}

void UnionFindSet::initial(string str1)
{
	_union_find_set[str1]=string("-1");
}

string UnionFindSet::find(string str)
{
	string father=str;
	do{
		str=father;
		father=_union_find_set[str];
	}while(father[0]!='-'&&!father.empty());
	if(father.empty())
		initial(str);
	return str;
}

bool UnionFindSet::unite(string ancestor1,string ancestor2)
{
	int size1,size2;
	if(ancestor1==ancestor2)
		return false;
	else{
		//C++11 is not support in gcc 4.6
		//size1=stoi(_union_find_set[ancestor1]);
		//size2=stoi(_union_find_set[ancestor2]);
		size1=atoi(_union_find_set[ancestor1].c_str());
		size2=atoi(_union_find_set[ancestor2].c_str());
		if(size1>=size2){
			_union_find_set[ancestor1]=ancestor2;

			stringstream ss;
			ss<<size1+size2;
			_union_find_set[ancestor2]=ss.str();
		}
		else{
			_union_find_set[ancestor2]=ancestor1;

			stringstream ss;
			ss<<size1+size2;
			_union_find_set[ancestor1]=ss.str();
		}
		return true;
	}
}

int main(int argc,char **argv)
{
	int t,m,i,j;
	scanf("%d",&t);
	for(i=0;i<t;++i){
		m=-1;
		scanf("%d",&m);

		UnionFindSet set;
		for(j=0;j<m;++j){
			string pair1,pair2;
			cin>>pair1>>pair2;
			if(set.find(pair1)==set.find(pair2)){
				if(set.bCircleNodeNumOdd(pair1,pair2)){
				printf("Case #%d: No\n",i+1);
			//	cout<<"	Same father : "<<set.find(pair1)<<endl;
				break;
				}
			}
			else {
				set.unite(set.find(pair1),set.find(pair2));
			}
		}
		if(j==m)
			printf("Case #%d: Yes\n",i+1);
		//printf("	m: %d ; size:%d\n",m,set._union_find_set.size());
	}
	return 0;
}


算法竞赛进阶指南:配套开源代码仓库的正确打开方式 算法竞赛是检验编程与逻辑思维能力的经典场景,其核心在于将数据结构、图论、动态规划等抽象知识转化为高效的 C++ 实现。一个精心组织的开源代码仓库,不仅提供了可编译运行的例题代码,还隐藏了竞赛选手的编码习惯与建图、优化等细节。通过对比自己的实现与标准代码,学习者能快速定位思维盲区,理解算法思想背后的工程取舍。在实际备赛中,结合在线评测平台进行验证与对拍,能够形成“阅读-编码-调试-反思”的闭环。对于正在啃《算法竞赛进阶指南》的读者,其配套的非侵权内容仓库正是这样一个桥梁——它绕开版权限制,将书中例题的代码与测 阅读详情

相关推荐

告别手动拖拽!PyQt5/PyQt6 QTableView列宽自适应窗口的三种实战方案(附性能对比)

本文详细介绍了PyQt5/PyQt6中QTableView列宽自适应窗口的三种实战方案,包括Stretch模式、resizeEvent手动计算和ResizeToContents模式,并附有性能对比。帮助开发者解决窗口大小变化时列宽不变的常见问题,提升用户体验和开发效率。

weixin_42538752的博客 234

并查集【通俗易懂】【知识点】

为了解释并查集的原理,我将举一个有爱的例子。  话说江湖上散落着各式各样的大侠,有上千个之多。他们没有什么正当职业,整天背着剑在外面走来走去,碰到和自己不是一路人的,就免不了要打一架。但大侠们有一个优点就是讲义气,绝对不打自己的朋友。而且他们信奉“朋友的朋友就是我的朋友”,只要是能通过朋友关系串联起来的,不管拐了多少个弯,都认为是自己人。这样一来,江湖上就形成了一个一个的帮派,通过两两之间的朋友...

不甘 3840

ThinkPHP+Layui开发的ERP管理系统

ERP采购生产销售系统,一款基于ThinkPHP+Layui开发的ERP管理系统,帮助中小企业实现ERP管理规范化,此系统能为你解决五大方面的经营问题:1.采购管理 2.销售管理 3.仓库管理 4.资金管理 5.生产管理,适用于:服装鞋帽、化妆品、机械机电、家具装潢、建材行业、快销品、母婴用品、办公用品、汽配汽修、生鲜农贸、手机通讯、数码家电、医药用品、制造业、信息技术服务行业等。提供全部无加密服务端和前端源代码,独立部署,不受限制。

u011092458的博客 788

并查集进化史(CS61B笔记)

并查集,也叫Disjoint Sets或Union-Find. 其不同底层实现的优缺点是什么,又有什么方法能改进.

qq_42103298的博客 452

《通信工程施工与管理》

制作馈线接头必须使用专用的工具,专用工具包括:馈线切割刀、馈线安全刀、小金属丝毛刷、固定尺寸或大号活动扳手、小号扁锉刀、细齿小手锯、接头扩孔器、3M防水胶或防水接头盒;如图所示,详情如表所示。

2302_78710464的博客 1653

重塑计算的五层蛋糕:解读黄仁勋CES2026演讲背后的AI新秩序与物理世界

2026年CES演讲揭示AI新纪元:从语言模型到物理智能 NVIDIA CEO黄仁勋在2026年CES演讲中描绘了计算产业的根本性变革。核心突破包括: 计算范式转移:从指令执行转向意图理解,智能体系统崛起 物理AI突破:发布Cosmos世界模型,通过合成数据训练AI理解物理定律 全新VeraRubin计算平台:6芯片协同设计,解决摩尔定律放缓与AI需求增长的矛盾 自动驾驶革命:推出具备推理能力的Alpamayo模型,实现L4级自动驾驶 演讲标志着AI正从数字世界迈向物理世界,NVIDIA通过全栈布局,正在重

老孙 | Ethan Sun 的博客:AI 智能体与 AI 原生软件的工程实践 1275

并查集的学习之路(论并查集如何成为女朋友)

简单种类并查集的万能做法: 例题:POJ 1703(看不懂这题代码的请忽略代码向下看,这只是个小菜) ac代码: #include &lt;iostream&gt; #include &lt;algorithm&gt; #include &lt;cstdio&gt; #include &lt;cstdlib&gt; #include &lt;cmath&gt; #include &lt;cstri...

你轻轻地走了 219

高分辨率航拍图像的目标检测切图优化策略

本文深入探讨了高分辨率航拍图像目标检测中的切图优化策略。针对大尺寸图像直接缩放导致小目标信息丢失的问题,文章详细阐述了基于重叠切割的核心方法,包括如何根据目标尺寸确定切图尺寸与重叠率,并提供了从切图到坐标还原的完整代码实现与避坑指南,有效提升检测精度与效率。

xk7n92h3p5m的博客 1113

超详细的并查集讲解 首发

/** 并查集呢,我想着以HDU1232 畅通工程为例子细讲; 这个题目应该很简单吧,就是求存在多少个连通分量; 并查集是一个什么东西,它主体包括三个东西:pre[i]数组,find函数,join函数; 那么这三个东西是什么鬼呢,分别表示的是 i的父节点称前导点,查找父节点的操作并进行优化的操作,看是否需要添加另一层关系添加新的前导点; 那么有了这三个部分之后我们可以干嘛呢 说一下它的功能吧:判断两

布呗之路 448

51单片机STC8G1K08驱动ws2812记录

使用51单片机控制17个2812灯,这里选择STC8芯片,最大频率可以达到35M,参考网上的各种文章案例,使用定时器做的时候实测做不到规格书要求的245-345ns,STC8G1K08不带PWM,所以只能使用nop来做,好在单片机在这里只有做编程灯的功能,省略测试过程,下面是程序,使用的是24MHz内部晶振 //设置一个灯珠 void SendOnePix(unsigned char *ptr) { unsigned char i,j; unsigned char temp; fo...

的博客 7322

【中项第三版】系统集成项目管理工程师 | 第 1 章 信息化发展

【中项第三版】系统集成项目管理工程师 | 第 1 章 信息化发展

静谧、淡雅 6577

并查集

并查集是快速实现大量数据的合并和查找,时间复杂度为O(log2n)  以下是两层并查集:(结点与自己的祖先直接相连)1&gt; 初始化 祖先赋为自己father[i=1~n] = i; 2&gt; 并:若总根不同,将两个结点的总根合并:第一个总根做第二个总根的祖先3&gt; 查:查看father是否相同#include &lt;iostream&gt; using namespace std; ...

_Gion 479

Java 类与对象 -- Java 语言的类与对象、构造器、static、final、包和 JAR

本篇文章我们将深入了解 Java 语言中的类与对象,探讨构造器、`static`、`final`、包和 JAR 文件。这些概念是面向对象编程的核心,对于理解和掌握 Java 至关重要。

栗筝i的博客 5038

华为OD机试必刷题:并查集算法详解与多语言实现

并查集是一种用于高效处理动态连通性问题的数据结构,其核心思想是通过维护一个森林结构来管理元素的分组关系。算法通过“查找”和“合并”两个基本操作,配合路径压缩与按秩合并优化,可实现近乎常数时间的查询与合并效率。在工程实践中,并查集广泛应用于社交网络好友关系、组件连通性检测、图论中的环检测等场景,是解决“动态团队归属”类问题的标准方案。本文以华为OD高频考题“We Are A Team”为例,深入剖析并查集在算法题中的应用,并提供C++、Java、JavaScript、Python四种语言的完整实现与避坑指南,

weixin_30421809的博客 379

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

蓝桥杯国赛扩散题解析:从暴力模拟到BFS与并查集优化

在算法竞赛中,面对大规模网格模拟问题,暴力枚举常因时空复杂度爆炸而失效。其核心原理在于将连续过程离散化,利用广度优先搜索(BFS)模拟扩散过程,并结合并查集高效处理集合合并与连通性查询。这种思路的技术价值在于,它能将看似复杂的连续空间问题转化为离散事件序列处理,大幅提升计算效率。典型应用场景包括网络传播模拟、图像处理中的区域生长及计算几何中的覆盖问题。本文以蓝桥杯国赛经典题目“扩散”为例,深入剖析如何通过离散化与BFS将问题转化为曼哈顿距离计算,并借助并查集优化求解过程,为处理类似网格模拟与连通性问题提供了

weixin_30567225的博客 422

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

寒假训练——2018.1.23

今天用了将近一天的时间看了欧拉路,拓扑还没怎么细看。欧拉路主要是在判断弱连通的时候用并查集,找出有几个欧拉通路,然后今天夹带着把字典序也看了看,因为饶齐的第一篇博客就是字典序+并查集+欧拉回路的判断,觉得来龙去脉已经弄懂了。欧拉路的概念性的东西不算少,无向图,有向图存在欧拉路的条件,还没有涉及到混合图那一块,只是把饶齐的这一块看完了。就是读题知道我要找什么,代码来回就是那些套路,明天打算把见过的题

20164225的博客 216

acm周末学习总结

这周做了洛谷上面的题目,还是发现很多自己的不足,最大的问题是思路不清晰。细节不到位。最近几周把精力集中在acm上,要为进入校队而努力了! 然后今天和一个舍友组了个队打了一场比赛,最后就是有5道题有思路却只ac了3道,并查集的题目我们都不会,用别的方法没做出来,暴力不是总会出奇迹。细节,还是得注意细节。英文读题有很大问题,不是不认识个别单词读不懂,而是读英文不习惯 ,太浮躁。多做思维模拟题目对理清细...

Nerdant 355

程序猿为什么会淡忘?

一 起因: (1)你是否有过这样的尴尬经历:明明昨天研究很熟悉的技术,今天却不能很好的领导讲解? (2)你是否有过这样的尴尬处境:明明之前做好的项目,过一段时间竟然把它统统忘记? (3)你是否有过这样的汗颜情景:自己非常熟悉的技术,突然一下子被一个爱刨根问题的”无招数的江湖小子“,给问的自己不知道如何回答? (4)你是否有过这样的纠结状况:明明记了N多次的算法,总是一次一次查看,再一次一次

ljhtwetwe的专栏 433

程序员为什么会淡忘?

一 起因: (1)你是否有过这种尴尬经历:明明昨天研究非常熟悉的技术。今天却不能非常好的领导解说? (2)你是否有过这种尴尬处境:明明之前做好的项目。过一段时间居然把它统统忘记? (3)你是否有过这种汗颜情景:自己很熟悉的技术。突然一下子被一个爱刨根问题的”无招数的江湖小子“。给问的自己不知道怎样回答? (4)你是否有过这种纠结状况:明明记了N多次的算法。总是一次一次查看,再一次一...

weixin_34130389的博客 99

1135. Connecting Cities With Minimum Cost

这个题目是leetcode的premuim 才能看的,网上看到别人贴出来了,学习一下。 一 题目 原文链接:https://blog.youkuaiyun.com/Csdn_jey/article/details/97611628 There are N cities numbered from 1 to N. You are given connections, where each connec...

bohu83的博客 837

2024年最全GitHub 上值得前端学习的数据结构与算法项目,前端开发基础学习

框架原理真的深入某一部分具体的代码和实现方式时,要多注意到细节,不要只能写出一个框架。算法方面很薄弱的,最好多刷一刷,不然影响你的工资和成功率😯在投递简历之前,最好通过各种渠道找到公司内部的人,先提前了解业务,也可以帮助后期优秀 offer 的决策。要勇于说不,对于某些 offer 待遇不满意、业务不喜欢,应该相信自己,不要因为当下没有更好的 offer 而投降,一份工作短则一年长则 N 年,为了幸福生活要慎重选择!!!开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

2401_84437691的博客 1232

书单 | 双十一薅当当羊毛4折囤书攻略

好书任何时候都可以买,但为什么要等到「双十一」?因为双十一会打折,能用平时3折左右的价格买到平时不怎么打折的书。我们联合电子工业出版社博文视点为奋战了一整年的猿媛们奉上一份安慰购书大礼包◆...

azl397985856的专栏 1106
上一篇: 《设计模式》笔记:代理模式vs适配器模式vs外观模式
下一篇: C++重载输入和输出操作符以及IO标准库中的刷新输入缓冲区残留字符问题
L_hunter
博客等级 码龄17年 44粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值