用c语言实现——并查集

题目描述
假如已知有n个人和m对好友关系(存于集合r)。如果两个人是直接或间接的好友(好友的好友的好友…),则认为他们属于同一个朋友圈。请写程序求出这n个人里一共有多少个朋友圈。

输入
输入包含多个测试用例,每个测试用例的第一行包含两个正整数 n、m,1 < = n,m< =100000。接下来有m行,每行分别输入两个人的编号f,t(1 < = f,t < = n),表示f和t是好友。 当n为0时,输入结束,该用例不被处理。

输出
对应每个测试用例,输出在这n个人里一共有多少个朋友圈。每组一行。

样例输入

5 3
1 2
2 3
4 5
3 3
1 2
1 3
2 3
0

样例输出

2
1

提示

例如,对于第一个例子:n = 5 , m = 3 , r = {{1 , 2} , {2 , 3} , {4 , 5}},表示有5个人,1和2是好友,2和3是好友,4和5是好友,则1、2、3属于一个朋友圈,4、5属于另一个朋友圈,结果为2个朋友圈。

代码实现如下

#include<iostream>
using namespace std;
int f[100005],n, m,k,sum=0;
void init()//先让每个人都知道自己,将其对应值给自己
{
    int i;
    for(i=1;i<=n;i++)
    {
        f[i]=i;
    }
}
int getf(int v)//递归找到最大的朋友
{
    if(f[v]==v)
        return v;
    else {
        f[v]=getf(f[v]);//压缩路径
        return f[v];
    }
}
void merge1(int v,int u)//合并两个圈子的函数
{
    int q1,q2;
    q1=getf(v);
    q2=getf(u);
    if(q1!=q2)//判断两个人是否否在同一个圈子。
    {
        f[q2]=q1;//按靠左原则,即让右边的人成为做边的人;
 
    }
}
int main()
{
    int i,x,y;
    while(cin >> n,n)
    {
        cin >>m;
    init();//初始化
    for(i=1;i<=m;i++)
    {
        cin >> x >> y;//输入每个人关系
        merge1(x,y);//合并子集
    }
    for(i=1;i<=n;i++)//判断有几个团体;
    {
        if(f[i]==i)
            sum++;
    }
    cout <<sum<<endl;
    sum=0;
 
    }
}
发布了18 篇原创文章 · 获赞 2 · 访问量 573

猜你喜欢

转载自blog.csdn.net/xiaoxiao66668/article/details/103319340