【UOJ 300】感冒病毒

【题目描述】:

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

【输入描述】:

输入的第一行是两个整数n和m,表示学生的数目和社团的数目,学生的编号为0到n-1。

接下来m行,每行首先是一个数ki,表示这个社团有ki个人,接下来ki个整数,表示这个社团里每个学生的编号aij。

【输出描述】:

输出为一行,包含一个整数。表示感染感冒病毒的人数。

【样例输入】:

100 4
2 1 10
5 10 13 11 12 14
2 0 1
2 9 2

【样例输出】:

7

【时间限制、数据范围及描述】:

时间:1s 空间:256M

对于 20%的数据:n<=100; m<=5;

另有 10%的数据:m=1;

对于100%的数据,3<=n<=30000

对于100%的数据,3<=m<=500

对于100%的数据,1<=ki<=n

对于100%的数据,0<=aij<n。

 

题解:简单的并查集模板啦,可以路径压缩。

 

#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
int n,m,k,fa[30005],fst,ans;
int find(int x){
   if(fa[x]==x) return x;
   return fa[x]=find(fa[x]);
}
int main(){
    freopen("300.in","r",stdin);
    freopen("300.out","w",stdout);
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
        fa[i]=i;
    //if(n==0 && m==0) break;
    for(int i=1;i<=m;i++){
        scanf("%d %d",&k,&fst);
        k--;
        while(k--){
            int now;
            scanf("%d",&now);
            fa[find(now)]=fa[find(fst)];
        }
    }
    int o=find(0);
    for(int i=0;i<n;i++)
        if(fa[find(i)]==o) ans++;
    cout<<ans;
    return 0;
}

 

posted @ 2019-07-03 16:58  #Cookies#  阅读(253)  评论(0编辑  收藏  举报