并查集的例题

本文介绍了一种使用并查集解决特定问题的方法。通过询问学生之间的关系来确定可能存在的宗教团体数量,避免直接询问学生个人信仰。利用并查集算法进行高效地数据处理和关系维护。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*题意为: 已知学校有n个学生 ,想知道有多少个宗教,但是不能一个一个问学生   ,已知两个一起的是一个宗教的,现可以问m对学生,请求出最多有多少个宗教    输入数据  10   4          2   3   4   5   4   8    5   8    答案为7                由题知采用并查集求解 (可看做二叉树 )     */

#include<iostream>

using namespace  std;


//const  int max = 5005;
int pa[1000];            //定义数组,用来存储结点
int rank[1000];          //定义秩,即某一个结点可容纳的结点数  
int ans;                                  //答案


void set(int x)                   //初始化每个结点,是自己就是一个根结点
{
pa[x] = x;
rank[x] = 0;
}


int find(int x)   //寻找结点的根
{
if (x != pa[x])              //判断自己的根结点是否是自己
{
pa[x] = find(pa[x]);
}
return pa[x];                       //返回找到的根结点
}


void  Union(int x, int y)  //联合函数 ,把两个结点连接起来
{
x = find(x);                         //先找到根结点
y = find(y);
if (x == y) //判断是否相等,如果相等就不用操作
{
return;
}
ans--;      //如果是相等的,则宗教总数就会少一
if (rank[x] > rank[y]) //看谁的秩大,即已经拥有的结点多,把稍等放在多的下面,为了减低树的高度,查找时方便
{
pa[y] = x;
}
else
{
pa[x] = y;
if (rank[x] == rank[y])
{
rank[y]++;
}
}
}


int main()
{
int m,n; 
int i;
while ((cin>>n,cin>>m)&&(n>0,m>=0))
{
for (i = 1; i <=n;i++)            //对每个都进行初始化
{
set(i);
}
ans = n;
int person1, person2;  
for (i = 0; i < m; i++)
{
cin >> person1 >> person2;   //输入两个要询问的对象
Union(person1, person2);      //联合
}
int k = 1;
cout <<"case" <<k<<":"<<ans<< endl;
k++;
cin >> n >> m;
}


return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值