并查集

并查集是快速实现大量数据的合并和查找,时间复杂度为O(log2n)

 

以下是两层并查集:(结点与自己的祖先直接相连)

1> 初始化 祖先赋为自己father[i=1~n] = i;

2> 并:若总根不同,将两个结点的总根合并:第一个总根做第二个总根的祖先

3> 查:查看father是否相同



#include <iostream>
using namespace std;

int n, m, q;                       //一共n个人,m对亲戚关系,q次查询
int father[10001];

int Find_f(int x) {                //找总根 
	if(x == father[x]) return x;  //说明x是总根 
	father[x] = Find_f(father[x]);
	return father[x];
}

int Unite(int a, int b) {          //合并 
	int f1 = Find_f(a);
	int f2 = Find_f(b);
	if(f1 == f2) return 0;        //f1 = f2 已经是亲戚关系 
	father[f2] = f1; 
	return 1;
}

int main() {
	int x, y, c, d;
	cin >> n >> m >> q;
	for(int i=1; i<=n; i++) father[i] = i; //初始化 
	for(int i=1; i<=m; i++) {
		cin >> x >> y;  
		Unite(x, y);                      //x、y成为亲戚 
	}
	for(int i=1; i<=n; i++) Find_f(i);     //上面Unite只是合并总根,总根下的子结点还没更新 
	for(int i=1; i<=q; i++) {
		cin >> c >> d;                    //查询c、d是不是亲戚 
		if(father[c] == father[d]) cout << "Yes" << endl;
		else cout << "No" << endl;
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值