并查集-union_find

详解:并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。

主要通过数组达成联系关系。

以此图为例,准备求解多少个团体及每个团体多少人(盗图的我来啦)

本博客主要以知识点复习为主

#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;
}

猜你喜欢

转载自blog.csdn.net/SMyName/article/details/81509902