并查集应用————好朋友

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;
}
发布了321 篇原创文章 · 获赞 51 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_33375598/article/details/104271609