PAT甲级-并查集-1107 Social Clusters解题思路

1107 Social Clusters (30 分)

在这里插入图片描述

思路

经典并查集
int findFather(int x) //这里其实可以加入路径压缩
就是构造找爸爸时的树更矮一点

代码

#include<bits/stdc++.h>
using namespace std;

const int N = 1010;
int father[N]; //存放父亲结点
int isRoot[N] ={
    
    0}; //记录每个结点是否作为某个集合的根结点
int course[N] = {
    
    0}; //记录前面谁喜欢这个活动,然后和它合并

void init(int n ){
    
       //初始化,每个人的爸爸是自己
    for(int i =1 ;i<=n;i++){
    
    
        father[i] = i;
    }
}


int findFather(int x) //这里其实可以加入路径压缩
{
    
    
    while(x!=father[x]){
    
    
        x = father[x];
    }
    return x;
}

void Union(int a,int b)  //实际上是合并爸爸
{
    
    
    int faA = findFather(a);
    int faB = findFather(b);
    if(faA != faB)
        father[faA] = faB;
}

int main(){
    
    
    int n ,k,h;
    char ch;
    scanf("%d",&n);
    init(n);

    for(int i=1;i<=n;i++)
    {
    
    
        scanf("%d%c",&k,&ch);
        for(int j =0;j<k;j++)
        {
    
    
            scanf("%d",&h);
            if(course[h]==0)
                course[h]= i;
            Union(i,course[h]);
        }
        
    }


    for(int i =1;i<=n;i++)
        isRoot[findFather(i)]+=1;

    int ans = 0;
    for(int i =1;i<=n;i++)
        if(isRoot[i]!=0)
            ans++;

    cout<<ans<<endl;

    sort(isRoot,isRoot+n+1);
    for(int i=n;i>=n-ans+1;i--)
    {
    
    
        if(i==n-ans+1)cout<<isRoot[i]<<endl;
        else cout<<isRoot[i]<<" ";
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43999137/article/details/114692512