详解:并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。
主要通过数组达成联系关系。
以此图为例,准备求解多少个团体及每个团体多少人(盗图的我来啦)
本博客主要以知识点复习为主
#include<bits/stdc++.h>
using namespace std;
const int Max=110;
int n,m; //n个人物 m个关系
int Friend[Max]; //记录各人物关系
int sum[Max]; //记录伙伴的个数
int ans_sum; //记录社团总数
int Maxn; //记录最大社团人数
int ans_per[Max]; //记录社团负责人
int ans_num[Max]; //记录每个社团人数
void init() //初始化人物关系
{
ans_sum=0;
memset(ans_per,0,sizeof(ans_per));
memset(ans_num,0,sizeof(ans_num));
Maxn=0;
for(int i=0;i<Max;i++)
{
Friend[i]=i; //开始所有人物只与自身有关系
sum[i]=1; //伙伴数目初始化为 1
}
}
int Search(int x)
{
if(x==Friend[x])
{
return x;
}
else
{
return Friend[x]=Search(Friend[x]); //指向朋友中最强的人,减少搜素时间
}
}
void Union(int p1,int p2)
{
int s1=Search(p1);
int s2=Search(p2);
if(s1!=s2) //判断两人是否属于一个社团
{
Friend[s1]=s2; //记录s1的朋友是 s2
sum[s2]=sum[s2]+sum[s1]; //继承 s1 的伙伴
}
}
void read()
{
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
Union(a,b); // a,b是朋友,建立关系
}
}
void output()
{
int number=0;
for(int i=1;i<=n;i++)
{
if(Friend[i]==i)
{
ans_sum++;
ans_per[++number]=i;
ans_num[number]=sum[i];
Maxn=max(Maxn,ans_num[number]);
}
}
printf("社团总数:%d\n",ans_sum);
for(int i=1;i<=number;i++)
{
printf("社团代表人物:%d\n",ans_per[i]); //其实没啥子用
printf("社团中的人数:%d\n",ans_num[i]);
}
printf("社团最多人数:%d\n",Maxn);
}
int main()
{
while(scanf("%d%d",&n,&m)!=-1) // n个人物 m种关系
{
init();
read(); //输入关系
output();
}
return 0;
}