并查集

并查集

在这里插入图片描述
如下图所示
在这里插入图片描述
所以我们就可以想一个办法,如何找到自家的老大。
先令每个人的老大就是自己,然后当遇到另一个和自己有关系的人的时候,便去问候一下对方的老大,比如今天某席大侠和某陈大仙女走进同一家面馆吃面,信竞中人,一言不合就要开始【哔~】,但当他们要开始【哔】之前,自然要问候一下对方的老大。我们可以用一个pre数组来存每一个人的老大
然后他们就委托自己的上级去找老大。

int find(int x)
{
	int r=x;
	while(pre[r]!=r) //席大侠和陈大仙女找到自己的上一级宋师兄等人 
		r=pre[r]; //一层层往上找 
	return r; //找出幕后老大何X
}

最终发现竟然是一个老大(还好没打起来!!!)
但如果不是一个老大,如当年武林大比之时,何X与黄(fang)勇各领风骚,都想称霸德瑞黑心集团,他们谁也不服谁,但一山不容二虎,这时就只好有一人得屈居人下。

void join(int x,int y)
{
	int fx=find(x),fy=find(y);
	if(fx!=fy)
		pre[fx]=fy;//屈居人下
}

这时就又有一个问题了,信竞中人,讲究雷厉风行,一个一个找上级太麻烦了,还不如直接找到老大
所以就变成了下面这样:
在这里插入图片描述

int find(int x)
{
	int i,j,r;
	r=x;
	while(r!=pre[r]) //不是老大
	{
		r=pre[r]; //向上找
	}
	i=x;
	while(i!=r) //把所有人的上级直接改为老大
	{
		j=pre[i];
		pre[i]=r;
		i=j;
	}
	return r;
}

所以但席大侠和陈大侠女再一起吃面时,他们就可以直接说出,老纸(娘)滴老大是何X!!

【完整代码】上面辣么多文字我也没看懂,还是看看代码吧

#include<bits/stdc++.h>
using namespace std;
int n,m,pre[10100];
int find(int x)
{
	int i,j,r;
	r=x;
	while(r!=pre[r])
	{
		r=pre[r];
	}
	i=x;
	while(i!=r)
	{
		j=pre[i];
		pre[i]=r;
		i=j;
	}
	return r;
}
void join(int x,int y)
{
	int fx=find(x),fy=find(y);
	if(fx!=fy)
	{
		pre[fx]=fy;
	}
}
int main()
{
	cin>>n>>m;
	int z,x,y;
	for(int i=1;i<=n;i++) pre[i]=i;
	for(int i=1;i<=m;i++)
	{
		cin>>z>>x>>y;
		if(z==1)
		{
			join(x,y);
		}
		if(z==2)
		{
			int p=find(x),q=find(y);
			if(p==q)
			{
				cout<<'Y'<<endl;
			}
			else
			{
				cout<<'N'<<endl;
			}
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值