题意:输入n,m分别表示学生人数和组数,然后输入m组数据,现在已经知道如果一个小组里面的一个人得病,那么该小组都有可能得病。而且已经知道0号学生已经得病,问:一共有多少人可能得病?
解法:并查集
用树高代表集合的大小,最后输出根为0的小组的人数就可以了!
#include <iostream>
#include<cstdio>
#define max_n 30005
int father[max_n];
int Rank[max_n];
int a[max_n];
using namespace std;
void start_union(int n)
{
for (int i = 0; i <= n-1; i++)
{
father[i] = i;
Rank[i] = 1;
}
}
int find(int r)
{
while (father[r] != r)
{
r = father[r];
}
return r;
}
void join(int x, int y)
{
int fx = find(x);
int fy = find(y);
if (fx == fy) return;
if (Rank[fx] >= Rank[fy])
{
father[fy] = fx;
Rank[fx] += Rank[fy];
}
else
{
father[fx] = fy;
Rank[fy] += Rank[fx];
}
}
int main()
{
int n,m;
while (scanf_s("%d%d", &n, &m) != EOF)
{
if (n == 0 && m == 0) break;
start_union(n);
while (m--)
{
int t;
scanf_s("%d", &t);
// memset(a,0,sizeof(a));
for (int i = 0; i<t; i++)
{
scanf_s("%d", &a[i]);
if (i != 0) join(a[i - 1], a[i]);
}
}
printf_s("%d\n", Rank[find(0)]);
}
return 0;
}