社交集群 并查集

  

当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。

输入格式:

输入在第一行给出一个正整数 N(≤),为社交网络平台注册的所有用户的人数。于是这些人从 1 到 N 编号。随后 N 行,每行按以下格式给出一个人的兴趣爱好列表:

Ki​​: [ ... [

其中(是兴趣爱好的个数,[是第j个兴趣爱好的编号,为区间 [1, 1000] 内的整数。

输出格式:

首先在一行中输出不同的社交集群的个数。随后第二行按非增序输出每个集群中的人数。数字间以一个空格分隔,行末不得有多余空格。

输入样例:

8
3: 2 7 10
1: 4
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4

输出样例:

3
4 3 1

并查集模拟即可
#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define LL long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define N 1020

int f[1020];
int ans[1020];
int vis[1020];
int find1(int x)
{
    int j=x;
    while(j!=f[j])
        j=f[j];
    int cur=x;
    if(cur!=j)
    {
        int t=f[cur];
        f[cur]=j;
        cur=t;
    }
    return j;
}
void union1(int x,int y)
{
        int x1=find1(x);
        int y1=find1(y);
       if(x1!=y1)f[x1]=y1;
    return ;
}
int sum[N];
int main()
{
    rep(i,0,1010)
    f[i]=i;
    int n;
    RI(n);
    while(n--)
    {
        int q;
        scanf("%d:",&q);

        int a;RI(a);vis[a]=1;
        rep(i,2,q)
        {
            int b;
            RI(b);vis[b]=1;
            union1(a,b);
        }
        sum[a]++;
    }
    int cnt=0;
    vector<int>v;
    v.clear();
    rep(i,1,1000)
    if(vis[i])
    {
        if(sum[i])ans[ find1(i) ]+=sum[i];
        if(f[i]==i)cnt++;
    }

    rep(i,1,1000)
    if(ans[i])
        v.push_back(ans[i]);

    sort(v.begin(),v.end(),greater<int>());
    cout<<cnt<<endl;

    rep(i,0,v.size()-1)
    {
     if(i!=0)printf(" ");
     cout<<v[i];
    }
    
}





猜你喜欢

转载自www.cnblogs.com/bxd123/p/10525635.html