hzwer模拟赛 感冒病毒

题目描述 Description

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

输入描述 Input Description

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

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

 

输出描述 Output Description

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

 

样例输入 Sample Input

100 4

2 1 10

5 10 13 11 12 14

2 0 1

2 9 2

 

样例输出 Sample Output

7

 

数据范围及提示 Data Size & Hint

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

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

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

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

/*
在合并的时候需要注意一下,社团和社团是通过人来连接的,所以要把社团所在集合的代表元素设为人
*/
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 60500;
int n,m,f[maxn];
int u,v,ru,rv,k;
bool vis[maxn];
int read(){
    char ch=getchar();
    int f=1,x=0;
    while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();};
    while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();};
    return x*f;
}
int findf(int x){
    return x == f[x] ? x : f[x] = findf(f[x]);
}
int main(){
    n = read();
    m = read();
    for(int i = 0;i <= n+m;i++) f[i] = i;
    vis[0] = true;
    for(int i = 1;i <= m;i++){
        k = read();
        for(int j = 1;j <= k;j++){
            u = read();
            v = n + i;
            u = findf(u);
            v = findf(v);
            if(vis[v]) vis[u] = true;
            f[v] = u;
        }
    }
    int ans = 0;
    for(int i = 0;i < n;i++) if(vis[findf(i)]) ans++;
    cout<<ans;
    return 0;
}

 

posted @ 2016-09-21 16:28  ACforever  阅读(449)  评论(0编辑  收藏  举报