C++ 并查集算法

并查集是一种树型数据结构,用于处理不相交集合的合并与查询。本文介绍了并查集的基本操作,包括初始化、查询和合并,并讨论了优化策略如路径压缩和按秩合并。此外,还提及了带权并查集和扩展域并查集的应用,以及推荐的洛谷编程题目供练习。
摘要由CSDN通过智能技术生成

目录:

        并查集简介

并查集的三种基本操作

        1、clean:将并查集进行初始化,其祖先是该元素本身。

·      2、find:查询一个元素属于哪个集合。

       3、Merge:合并两个集合。

优化并查集

        1、路径压缩

        2、按秩合并 

带权并查集

扩展域并查集

并查集例题推荐

        洛谷:

                P3367 【模板】并查集

                P1551 亲戚

                P2820 局域网

                P1955 [NOI2015] 程序自动分析

                P2024 [NOI2001] 食物链(扩展域并查集)

                P1196 [NOI2002] 银河英雄传说(带权并查集)


并查集简介:

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

        并查集是一种树型的数据结构,用于处理一些不相交集合(disjoint sets)的合并及查询问题。常常在使用中以森林来表示。

                                                                                                                                     -- -- 百度百科

        简单来说:并查集是一种可以维护若干个不重叠的集合或无向图的连通块(也可以理解为一种集合)的数据结构。

        给大家画一个并查集的简图,以便大家了解。

 

并查集的三种基本操作:

        1、clean:将并查集进行初始化,其祖先是该元素本身。

·      2、find:查询一个元素属于哪个集合。

       3、Merge:合并两个集合。

        为了实现并查集,对于每一个集合,要确定集合唯一的表示方法。在并查集中,在每个集合中选取一个元素,代表整个集合,这个元素,就是集合的祖先。这样以来,我们只需要判断两个元素所在集合的代表元素是否相同,就可以判断其是否在一个集合内。

【代码实现】

int fa[100001];//记录元素的祖先
void clean()//初始化
{
	for(int i=1;i<=n;i++)
	{
		fa[i]=i;
	}
}
int find(int k)//寻找该元素的祖先
{
	 while(k!=fa[x])
    {
        x=fa[k];
    }
    return k; 
}
void add(int x,int y)//合并两个集合
{
	x=find(x);
	y=find(y);
	if(x!=y)
	{
		fa[x]=y;
	}
}

优化并查集:

        1、路径压缩:

                所谓路径压缩就是在连接的时候把每一个子节点都连接到祖先节点上。

                路径压缩运行速度较快,也是现阶段较为常用的优化方法,但路径压缩会改变树的形      态,不可以撤销操作或可持久化。

        

【代码实现】

int fa[100001];//记录元素的祖先
void clean()//初始化
{
	for(int i=1;i<=n;i++)
	{
		fa[i]=i;
	}
}
int find(int k)//寻找该元素的祖先
{
	if(fa[k]==k)
	{
		return k;
	}
	return fa[k]=find(fa[k]); 
}
void add(int x,int y)//合并两个集合
{
	x=find(x);
	y=find(y);
	if(x!=y)
	{
		fa[x]=y;
	}
}

        2、按秩合并 :

                所谓按序合并就是记录连接中两个树的高度,由低的连接到高的上,通常也可以记录 树  的大小。

                按秩合并的运行速度略慢与路径压缩,但是按秩合并不会改变树的形状态,多用于可撤  销并查集和可持久化并查集中。

【代码实现】

int fa[1000001];//记录祖先元素
int h[1000001];//记录深度
void clean(int n)//初始化 
{
	for (int i=0;i<=n;i++) 
    {
		fa[i]=i;
		rank[i]=0;
	}
}
int find(int k)//查找该元素的祖先
{
	if(fa[k]==k) 
    {
		
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值