好朋友
题目描述
有一个叫做“数码世界”奇异空间,在数码世界里生活着许许多多的数码宝贝,其中有些数码宝贝之间可能是好朋友,并且数码宝贝世界有两条不成文的规定:
第一,数码宝贝A和数码宝贝B是好朋友等价于数码宝贝B与数码宝贝A是好朋友
第二,如果数码宝贝A和数码宝贝C是好朋友,而数码宝贝B和数码宝贝C也是好朋友,那么A和B也是好朋友
现在给出这些数码宝贝中所有好朋友的信息问:可以把这些数码宝贝分成多少组,满足每组中的任意两个数码宝贝都是好朋友,而且任意两组之间的数码宝贝都不是好朋友
输入格式
输入的第一行有两个正整数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;
}