题目描述
一种感冒病毒正在学校里传播,这所学校有n个学生,m个学生社团,每个学生可能参加了多个社团,因为同一个社团的学生交流较多,所以如果一个学生感染上感冒病毒,那么他所在的社团里的所有学生都会感染上感冒病毒,现在已知0号学生感染上感冒病毒,问现在有多少人会感染上感冒病毒。输入
输入文件:suspects.in输入的第一行是两个整数n和m,表示学生的数目和社团的数目,学生的编号为0到n-1。
接下来m行,每行首先是一个数ki,表示这个社团有ki个人,接下来ki个整数,表示这个社团里每个学生的编号aij。
输出
输出文件:suspects.out输出为一行,包含一个整数。表示感染感冒病毒的人数。
输入样例
100 42 1 10
5 10 13 11 12 14
2 0 1
2 9 2
输出样例
7数据范围
对于100%的数据,3<=n<=30000对于100%的数据,3<=m<=500
对于100%的数据,1<=ki<=n
对于100%的数据,0<=aij<n。
题解
正解其实是并查集啦,但是应为空间太大了。所以以下只是我在“不用白不用”的想法支配下写的。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<algorithm>
#define inf 1<<30
using namespace std;
int n,m,s[502],a[30002];
int zz,head[30002];
struct bian{int to,nx;} e[15000002];
int pd[30002],ans;
void insert(int x,int y)
{
zz++; e[zz].to=y; e[zz].nx=head[x]; head[x]=zz;
zz++; e[zz].to=x; e[zz].nx=head[y]; head[y]=zz;
}
void init()
{
scanf("%d%d",&n,&m);
int i,j;
for(i=1;i<=m;i++)
{scanf("%d",&s[i]);
for(j=1;j<=s[i];j++)
{scanf("%d",&a[j]);
if(j>1) insert(a[j-1],a[j]);
}
}
}
void dfs(int x)
{
if(pd[x]) return ;
pd[x]=1; ans++;
int i;
for(i=head[x];i;i=e[i].nx) dfs(e[i].to);
}
int main()
{
freopen("suspects.in","r",stdin);
freopen("suspects.out","w",stdout);
init(); dfs(0);
printf("%d\n",ans);
return 0;
}