1107 Social Clusters(30 分)

明显是并查集的问题,但是一开始不知道怎么合并,参考的《算法笔记》的答案,每次碰到一个爱好,就给这个爱好设置为有这个爱好的人,这样就有了合并对象:人和有这个爱好的人
剩下的就是模板了,初始化,查找根节点,合并

#include
#include
#include
#include
using namespace std;
const int maxn = 1e3 + 10;
int father[maxn], course[maxn], cnt[maxn];
int n;
void init()
{
    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 fa = findfather(a);
    int fb = findfather(b);
    father[fa] = fb;
}
int main()
{
    scanf("%d", &n);
    init();
    for (int i = 1; i <= n; i++)
    {
        int k;
        scanf("%d:", &k);
        while (k--)
        {
            int x;
            scanf("%d", &x);
            if (course[x] == 0)course[x] = i;
            Union(course[x], i);
        }
    }
    for (int i = 1; i <= n; i++)
        cnt[findfather(father[i])]++;
    vectora;
    for (int i = 1; i <= n; i++)
    {
        if (cnt[i] != 0)a.push_back(cnt[i]);
    }
    sort(a.begin(), a.end(), greater());
    printf("%d\n", a.size());
    for (int i = 0; i < a.size(); i++)
    {
        printf("%d", a[i]);
        if (i != a.size() - 1)printf(" ");
    }
    return 0;
}

你可能感兴趣的:(1107 Social Clusters(30 分))