并查集

Posted johnfllora

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并查集相关的知识,希望对你有一定的参考价值。

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

举一个例子

假设有A B C  D    E五个人

A ,D两人感冒了。

 A和B玩传染给了 B ,B和C玩传染给了C 

D和E玩传染到了 E

技术图片

 

E只和D接触过,所以D E是一种同类型感冒。

B和A接触染了感冒,C和B接触有了感冒,所以A B C 是一种同类型感冒。

但一个个病友形成圈子后感染源头是谁,谁感染的感冒都不要紧,关键问题是根据不同的感冒类型治病,ABC一种,DE一种。

开始并查集的三步走 初始化 查找 合并。

1.初始化

定义一个数组对该数组每个值赋值其本身

2.查找

找到是谁感染的病,最后形成一个或多个病友圈,每个病友圈都有相对应的治疗方法对症下药,也就是找到根节点。

核心代码

1 rott(long    long int    rs)
2 {
3     long    long int    i,j;
4     i=rs;
5     while(rs!=pre[rs])//找病原体
6     rs=pre[rs];
7     
8     return    pre[rs];//返回老大 
9 }

3.合并

一般输入的两个数一起玩的就会互相感染,所以把他们两个合并起来看看是否有病友圈。

	          long	long int s1,e1;//一个圈的人
			 scanf("%lld%lld",&s1,&e1);
			 long	long int	r1=rott(s1);  //找他是否被感染
			 long	long int	r2=rott(e1); //同理
			 if(r1!=r2)
			 {
			 	pre[r1]=r2; //找根节点
				 mp--; //独立的个体少一 
			 }
		

  最后完整代码

#include<stdio.h>
long	long	pre[2000000]; //里面的老哥个个都是人才
rott(long	long int	rs)
{
	long	long int	i,j;
	i=rs;
	while(rs!=pre[rs])//找上级 
	rs=pre[rs];
	while(i!=rs)
	{
		j=pre[i];
		pre[i]=rs;
		i=j;
	}
	return	pre[rs];//返回老大 
}
int main()
{
	long	long int	n,m;
	while(scanf("%lld%lld",&n,&m)!=EOF)
	{
		long	long int	i,j;
		long	long int mp=n; 
		for(i=1;i<=n;i++)
		pre[i]=i;  //每个人都是自己生活的主宰
		while(m--) //分久必合合久必分
		{
			long	long int s1,e1;//一个圈的人
			 scanf("%lld%lld",&s1,&e1);
			 long	long int	r1=rott(s1);
			 long	long int	r2=rott(e1);
			 if(r1!=r2)
			 {
			 	pre[r1]=r2; 
				 mp--; //独立的个体少一 
			 }
		
		}
		 	printf("%lld
",mp);
	}
 } 

  

以上是关于并查集的主要内容,如果未能解决你的问题,请参考以下文章

想要学会并查集吗?看我四十行代码实现它

树--12---并查集

笔记并查集---无向图处理代码模板及类型题

并查集

力扣 每日一题 886. 可能的二分法难度:中等,rating: 1794(并查集 / 拆点优化的扩展域并查集)

并查集