并查集+例题

一、引入

思考下面题目(并查集板子题)

洛谷P1551 

二、概念

并查集是⼀种⾮常精巧⽽实⽤的树形数据结构,他主要是处理⼀些 不相交集合的合并和查询 的问
题。不相交集合,顾名思义,就是两个集合的交集为空集的⼀些集合。⽐如 1 3 5 2 4 6 ,他俩的交集为空集。就是不相交集合。像2 3 5 1 3 5 就不是不相交集合。
使⽤并查集时,⾸先会存在⼀组不相交的动态集合 S={S1, S2, ,Sk} ,⼀般都会使⽤⼀个整数表示
集合中的⼀个元素。
每个集合可能包含⼀个或多个元素,并选出集合中的某个元素作为代表。每个集合中具体包含了
哪些元素是不关⼼的,具体选择哪个元素作为代表⼀般也是不关⼼的。我们关⼼的是,对于给定的元素,可以很快的找到这个元素所在的集合(的代表),以及合并两个元素所在的集合,⽽且这些操作的时间复杂度都是常数级。

三、思路 

并查集用树型结构实现
用双亲表示法:
int f[x]=y;x节点的父亲是y
合并两个集合(即两棵树):合并两棵树的根节点:先找到各自的根节点,把根节点设立父子关系即可
查询两个节点是否在同一个集合(树):找到两个节点的根节点,看根节点是否相同
如何找根节点?
i=4;//i是要找父亲的节点
while(f[i]!=i)//令根节点的f[x]=x;
{
    i=f[i];
}

四、例题代码

#include <stdlib.h>
#include <stdio.h>
# include <string.h>
//洛谷P1551 
int n,m,p;
int f[5005];
//非递归版
/*int find(int x)
{
	while(f[x]!=x)
	{
		x=f[x];
	}
	return x;
}*/
//递归版
int find(int x)
{
	if(f[x]==x)
	{
		return x;
	 } 
	else{
		//return find(f[x]);//普通方法(未优化)
		return f[x]=find(f[x]);//路径压缩(优化方法) 
	}
}
int main()
{
	int x,y,px,py;
	scanf("%d %d %d",&n,&m,&p);
	//初始化f[i]=i
	for(int i=1;i<=n;i++)
	{
		f[i]=i;
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d",&x,&y);
		px=find(x);//px是x的父亲
		py=find(y);
		
		f[px]=py;
		//f[py]=px;
	}
	for(int i=1;i<=p;i++)
	{
		scanf("%d %d",&x,&y);
		px=find(x);
		py=find(y);
		if(px==py)
		{
			printf("Yes\n");
		}
		else{
			printf("No\n");
		}
	}
	return 0;	 
}

五、并查集用处

 1.和其他算法结合

2.是其他算法的中间过程

  • 21
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值