好朋友(并查集)

好朋友

题目描述

有一个叫做“数码世界”奇异空间,在数码世界里生活着许许多多的数码宝贝,其中有些数码宝贝之间可能是好朋友,并且数码宝贝世界有两条不成文的规定:

第一,数码宝贝A和数码宝贝B是好朋友等价于数码宝贝B与数码宝贝A是好朋友

第二,如果数码宝贝A和数码宝贝C是好朋友,而数码宝贝B和数码宝贝C也是好朋友,那么A和B也是好朋友

现在给出这些数码宝贝中所有好朋友的信息问:可以把这些数码宝贝分成多少组,满足每组中的任意两个数码宝贝都是好朋友,而且任意两组之间的数码宝贝都不是好朋友

yangli.png

输入格式

输入的第一行有两个正整数n(n <= 100)和m(m <= 100),分别表示数码宝贝的个数和好朋友的组数,其中数码宝贝编号为1~n。

输出格式

输出一个整数,表示这些数码宝贝可以分成的组数

样例输入1

4 2

1 4

2 3

样例输出1

2

扫描二维码关注公众号,回复: 12501794 查看本文章

样例输入2

7 5
1 2
2 3
3 1
1 4
5 6

样例输出

3

/*
 *@Author LeeG
 *@Date	2020-10-15 15:40
 *@Content 好朋友(并查集) 
*/
#include <bits/stdc++.h>
using namespace std;
int n, m;
int father[100];

int findFather(int x){		 
	int a = x;
	while(x != father[x]){
		x = father[x];		//先找到根结点 
	}
	//把路径上所有的结点的根结点都改成x
	while(a != father[a]){	//路径压缩,优化查找性能
		int z = a;
		a = father[a];
		father[z] = x;
	} 
	return x;
} 

void Union(int a, int b){
	int fa = findFather(a);
	int fb = findFather(b);
	if(fa != fb){			//判断是否在同一个集合中 
		father[fb] = fa;
	}
}

/*
测试数据:
7 5
1 2
2 3
3 1
1 4
5 6 
*/
int main(){
	cin>>n>>m;
	//1. 初始化father数组,所有结点初始化根结点为本身自己 
	for(int i = 1; i <= n; i++){
		father[i] = i;
	} 
	for(int i = 0; i < m; i++){
		int a, b;
		cin>>a>>b;
		Union(a, b);			//合并a和b所在的集合 
	}
	int ans = 0;
	int s[10001];
	memset(s, 0, sizeof(s));
	for(int i = 1; i <= n; i++){
		int temp = findFather(i);
		if(s[temp] == 0){
			ans++;
			s[temp] = 1;
		}
	}
	cout<<ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44723496/article/details/109100594