1107 Social Clusters (30 分)

题意

有N个人,每个人喜欢若干项活动,如果两个人有任意一个活动相同,那么就称他们处于同一个社交网络(若A和B属于同一个社交网络,B和C属于同一个社交网络,那么A、B、C属于同一个社交网络)。求这N个人总共形成了多少个社交网络。

思路

如果A和B是好朋友,并且B和C是好朋友,那么A和C也是好朋友。本题中判断两个人是好朋友的条件为他们有公共喜欢的活动,因此不妨开一个数组hobby,其中
hobby[h]用以记录第一个喜欢活动h的人的编号,这样的话find(hobby[h])就是这个人所在的社交网络的根结点。于是,对当前读入的人的编号i和他喜欢的每一个活动h,只需要合并i与hobby[h]即可。

const int N=1010;
int p[N];
int cnt[N];
int hobby[N];
int n;

int find(int x)
{
    if(x != p[x]) p[x]=find(p[x]);
    return p[x];
}

int main()
{
    cin>>n;

    for(int i=1;i<=n;i++) p[i]=i,cnt[i]=1;

    for(int i=1;i<=n;i++)
    {
        int k;
        scanf("%d:",&k);

        for(int j=0;j<k;j++)
        {
            int x;
            scanf("%d",&x);
            if(hobby[x] == 0)
                hobby[x]=i;
            else
            {
                int pa=find(i),pb=find(hobby[x]);
                if(pa != pb)
                {
                    p[pa]=pb;
                    cnt[pb]+=cnt[pa];
                    cnt[pa]=0;
                }
            }
        }
    }

    vector<int> res;
    for(int i=1;i<=n;i++)
        if(cnt[i])
            res.pb(cnt[i]);

    cout<<res.size()<<endl;
    sort(res.begin(),res.end(),greater<int>());
    for(int i=0;i<res.size();i++)
        if(i) cout<<' '<<res[i];
        else cout<<res[i];
    cout<<endl;
    //system("pause");
    return 0;
}
posted @ 2021-02-28 11:04  Dazzling!  阅读(23)  评论(0编辑  收藏  举报