并查集的初步理解及解题模板样例

并查集:
两天前对于并查集通过看啊哈算法书上神奇的树这一章节,第四小节,擒贼先擒王对于并查集算法有了一个最基础的认识。
并查集呢就是说给你一些人的关系,让你对他们进行分类,就像树一样,有一个树根,可以有很多孩子,只要是一个团伙的就在一棵树上;目前来说我做了几道题遇到的就是分出题目所给的数据有几个团伙(也就是有几棵树),还有就是让其中的一个得病,给你有一些数据(他们之间的关系),分好类以后(树建成),看看跟得病的人一个团伙的有几个人,其实吧这些题目(就目前遇到的)都是换汤不换药,都可以用同一个解题模来做题(只是在输入输出的地方需要做一些改进)。好了,下面我给出一组数据对其进行讲解
给出十组数据,并且这十组数据中的每两个人之间都是有关系的,我们就假设这是好几伙强盗(看最后能分成几棵树),并且假设左边的是右边的老板(俗称头头),
我们用一个数组来记录他们的老板是谁,最开始的时候他们自己就是自己的老板所以可以用一个for循环来搞定例如第一组数据就是f[2]=1了,f[1]还是1,根据靠左原则左边的数变成了右边的数老板所以f[2]就变成了1(后面的就没这么简单了还牵扯到路径的压缩问题)

1 2
3 4
5 2
4 6
2 6
7 11
8 7
9 7
9 11
1 6

第一组数据,刚才已经说过f[2]=1了,f[1]=1,
在这里插入图片描述
第二组数据f[4]=3,f[3]=3,其他的(第一组数据内容还不变),现在3变成了4的老板,1变成了2的老板
数组变化
f[2]=1,f[1]=1,f[4]=3,f[3]=3,
在这里插入图片描述
第三组根据规则2的老板是5,但是现在f[2]=1,既然遇到这种问题(规则不能变左边的是一定要变成右边的老板的)所以让5直接找2的老板1,让1也变成5的下属,现在2的老板还是5,同时也是1,
数组变化
f[1]=5,f[2]=1(是5的间接下属5还是他的老板),f[4]=3,f[3]=3,f[5]=5在这里插入图片描述
第四组数据6的老板是4这时候就用到俗称的路径压缩问题了,
由与4的老板是3,6的老板是4,这时候直接找3(直接找老板3,4是下属他不顶事啊),所以6就变成了3的直接下属(6是来做下属的跟上一个可不一样因为上一个是要当boss的,不理解的话再回头去看看)
数组变化
f[2]=1,f[1]=5,f[4]=3,f[3]=3,,f[6]=3;
在这里插入图片描述
第五组数据.6要变成2的下属,问题是6和2现在都是下属并且在两个团伙里面怎么办呢,还是刚才的问题有事情直接找老板,再找2最大老板是进行了数据压缩,2也变成了5的直接下属(因为他是一定要找到最大老板了找过后他肯定会知道它的最大老板是谁),(顺便说一句以后在遇到这样的,在有一个要找最大老板时候跟他在一条线上的都会变成老板的直接下属这也是路径压缩
在这里插入图片描述
现在找到了2的老板是5,6的老板是3,老板跟老板谈,还是刚才问题6是要做下属的,自然就接着6的老板3也变成了5的直接下属;
在这里插入图片描述
这算是一棵树,后面的也按照刚才的方法也会建成一棵树,、
只是最后一组数据也会加在第一棵树上,只是他会变成一次路径压缩,6的老板是,5只不过在赵老板的过程中6从间下属接变成了直接下属,1的老板是5,
下面我给出建好后的图形,另一颗树的建成可以自行尝试
在这里插入图片描述
模板代码:

#include<stdio.h>
int n,m,f[50005];
//初始化数组
void init()
{
	int i;
	for(i=1; i<=n; i++)
	   f[i]=i;
	return;
}
//找他的老板
int getf(int v)
{
	if(f[v]==v)
	return v;
	else
	{
		f[v]=getf(f[v]);
		return f[v];
	}
}
void merge(int v,int u)
{
	int t1,t2;
	t1=getf(v);//t1是v的老板,t2是u的老板
	t2=getf(u);
	if(t1!=t2)如果不是同一人就按照靠左原则
	{
		f[t2]=t1;
	}
	return;
}
int main()
{
	int i,x,y,t;
	while(scanf("%d %d", &n,&m),n!=0&&m!=0)
	{
		  t=0;
		init(); 
		for(i=1; i<=m;i++)
		{
			scanf("%d %d", &x,&y);
			merge(x,y);
		}
		for(i=1; i<=n; i++)
		{
			if(f[i]==i)
			t++;
		}
		printf("%d\n", t);
	}
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮皮皮皮皮皮皮卡乒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值