码迷,mamicode.com
首页 > 其他好文 > 详细

并查集

时间:2020-01-23 19:43:53      阅读:70      评论:0      收藏:0      [点我收藏+]

标签:highlight   abc   相对   节点   main   初始化   mic   class   自己   

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

举一个例子

假设有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\n",mp);
	}
 } 

  

并查集

标签:highlight   abc   相对   节点   main   初始化   mic   class   自己   

原文地址:https://www.cnblogs.com/johnfllora/p/12231031.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!