1. 程式人生 > >7-8 參與者人數 (20 分)

7-8 參與者人數 (20 分)

臨沂大學有很多社團,一個學生可能會加入多個社團。為了活躍大學生業餘生活,增強體育運動積極性,臨沂大學讀書社團決定舉行大學生跳繩比賽,要求該社團成員必須參加。為了擴大影響,要求只要其他社團有一個人參加,那麼該社團中的每一個人都必須參加。求參加比賽至少多少人?

輸入格式:

輸入第一行包含兩個整數n和m,n(0 < n <= 30000)表示學生的數目,m(0 <= m <= 500)表示社團的數目。每個學生都有一個唯一的編號,編號取值為0到n-1,編號為0的社團是讀書社團。 接下來有m個社團的名單,每個社團的名單在輸入中為一行。每一行先輸入一個數k表示社團總人數。接著是社團中k個成員的編號。

輸出格式:

輸出一個數佔一行,表示參加比賽的總人數。

輸入樣例:

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

輸出樣例:

4

程式碼:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int n,m,k,x,z,t,num,f[30005];
 5 int getf(int x){
 6     if(f[x] == x)
 7         return f[x];
 8     return f[x] = getf(f[x]);
9 } 10 void merge(int x,int y){ 11 int tx = getf(x); 12 int ty = getf(y); 13 if(tx != ty) 14 f[ty] = tx; 15 return; 16 } 17 int main(){ 18 for(int i = 0;i < 30005;i++) 19 f[i] = i; 20 scanf("%d%d",&n,&m); 21 for(int i = 0;i < m;i++){ 22 scanf("
%d%d",&k,&x); 23 if(i == 0) 24 t = x;//標記讀書社團中的一個人 25 for(int j = 1;j < k;j++){ 26 scanf("%d",&z); 27 merge(x,z); 28 } 29 } 30 for(int i = 0;i < 30005;i++) 31 if(getf(t) == getf(i))//找在一個集合裡的 32 num++; 33 printf("%d\n",num); 34 return 0; 35 }
View Code