模拟赛 感冒病毒(时间限制:1s;空间限制:256MB)

题目描述

一种感冒病毒正在学校里传播,这所学校有n个学生,m个学生社团,每个学生可能参加了多个社团,因为同一个社团的学生交流较多,所以如果一个学生感染上感冒病毒,那么他所在的社团里的所有学生都会感染上感冒病毒,现在已知0号学生感染上感冒病毒,问现在有多少人会感染上感冒病毒。

输入

输入文件:suspects.in
输入的第一行是两个整数n和m,表示学生的数目和社团的数目,学生的编号为0到n-1。
接下来m行,每行首先是一个数ki,表示这个社团有ki个人,接下来ki个整数,表示这个社团里每个学生的编号aij。

输出

输出文件:suspects.out
输出为一行,包含一个整数。表示感染感冒病毒的人数。

输入样例

100 4
2 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

题解

正解其实是并查集啦,但是应为空间太大了。所以以下只是我在“不用白不用”的想法支配下写的。

#include
#include
#include
#include
#include
#include
#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;
}

你可能感兴趣的:(搜索)