1 题目
Sample Inpu1t:
4 2
1 4
2 3
Sample Output1:
2
Sample Input2:
7 5
1 2
2 3
3 1
1 4
5 6
Sample Output2:
3
2 解析
2.1 题意
给出数码宝贝的个数与关系,给出数码宝贝分成的组数
2.2 思路
- 给出的组数实际为并查集的集合个数
- 1 用给出的关系建立并查集
- 2 用一个专门的数组查来记录集合的根结点个数
- 3 根据记录的集合的根结点个数来输出集合个数
3 参考代码
#include <cstdio>
const int MAXN = 110;
int father[MAXN];//存放父结点
int isRoot[MAXN] = {0};//每个结点是否为某个集合的根结点
void Init(int n){
for (int i = 1; i <= n; ++i)
{
father[i] = i;
isRoot[i] = 0;
}
}
int findFather(int x){//查找x所在的根结点
int a = x;
while(x != father[x]){
x = father[x];
}
//路径压缩
while(a != father[a]){
int z = a;
a = father[a];
father[z] = x;
}
return x;
}
void Union(int a, int b){//合并a与b所在的集合
int faA = findFather(a);
int faB = findFather(b);
if(faA != faB){
father[faA] = faB;
}
}
int main(int argc, char const *argv[])
{
int n, m, a, b;
scanf("%d%d", &n, &m);
Init(n);//初始化
for (int i = 0; i < m; ++i)
{
scanf("%d%d", &a, &b);//输入两个好朋友的关系
Union(a, b);//合并a和b所在集合
}
for (int i = 1; i <= n; ++i)//
{
isRoot[findFather(i)] = 1;
}
int ans = 0;
for (int i = 1; i <= n; ++i)//记录集合数目
{
ans += isRoot[i];
}
printf("%d\n", ans);
return 0;
}