题目链接:https://codeforces.com/group/5yyKg9gx7m/contest/270506/problem/F
思路
很明显是个并查集,不过在并查集的基础上要统计每个节点的所有子结点的数量,最后遍历每个结点,输出其根节点的所有子节点数就ok。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<cstring>
#include<climits>
#include<vector>
#include<queue>
#include<stack>
#define ll long long
using namespace std;
int N, M;
int fa[500001];//记录每个节点的当前根节点
int co[500001];//记录每个节点的子节点数+1(因为要包括自己)
int find(int x)//寻找x的根节点
{
if (x == fa[x])
return x;
else
return fa[x] = find(fa[x]);
}
int main()
{
cin >> N >> M;
for (int i = 1; i <= N; i++)
{
fa[i] = i;//初始化
co[i] = 1;
}
for (int i = 1; i <= M; i++)
{
int k;
int t;
cin >> k;
if (k==0)
continue;
cin >> t;
k--;
for (int i = 0; i < k; i++)
{
int num;
cin >> num;
int x = find(t);
int y = find(num);
if (x != y)//如果两个点的根节点不同,说明两个人不在一个大团体内,就将两个人的团体融合
{
fa[y] = x;
co[x] += co[y];
}
}
}
for (int i = 1; i <= N; i++)
printf("%d ", co[find(i)]);
return 0;
}
来源:CSDN
作者:bllovepigpig
链接:https://blog.csdn.net/bllovepigpig/article/details/104791072