并查集模板题之压缩路径---家族关系

题目:
题目描述:


分析:这也是一道并查集的模板题,但是区别于上一道更简单的模板题----->上一题较简单模板题链接
我们这次需要使用路径压缩,因为题目数据比较大且符合路径压缩的需求,具体压缩方式如图:在这里插入图片描述
我们将每个节点的父亲节点都让它成为这个集合的老祖宗节点,这样在遍历集合个数的时候就可以直接找到它的老祖宗是否一样来判定他们是否有血缘关系;具体内容如下代码实现:

#include"iostream"//本代码主要分析路径压缩,详细参照上述链接模板题
using namespace std;
const int N=1e6+5;
int fa[N];
int find_fa(int i){
	/*递归实现路径压缩
	if(fa[i]==i)
	return fa[i];
	else {
	fa[i]=find_fa(fa[i]);
	return fa[i];}
    */
	while(fa[i]!=i)
	{
		fa[i]=fa[fa[i]];//注意理解这句话,分析fa[i]的变化情况,可以通过添加代码打屏幕上查看fa的变化
		i=fa[i];//将i遍历到父亲的父亲节点上
	}
	return i;
	
}
int unionn(int x,int y){
	int fa_a=find_fa(x);
	int fa_b=find_fa(y);
	if(fa_a!=fa_b){
		fa[fa_a]=fa_b;
	}
}
int main(){
	int n,m,k;
	cin>>n>>m;
	for(int i=1;i<=n;i++) fa[i]=i;
	while(m--){
		int x, y;
		cin>>x>>y;
		unionn(x,y);
		}
	cin>>k;
	
	while(k--){
		int x,y;
		cin>>x>>y;
		if(find_fa(x)==find_fa(y))//对两个数据的老祖宗节点分析是否相同
		cout<<"YES"<<endl;
		else
		cout<<"NO"<<endl;
	}
	for(int i=1;i<=n;i++) cout<<fa[i]<<endl;
	return 0;
}

ps:我看到的较好的并查集分析博客园
作者:CYJB
出处:http://www.cnblogs.com/cyjb/
GitHub:https://github.com/CYJB/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值