7-25 朋友圈 (25 分)

7-25 朋友圈 (25 分)

某学校有$N$个学生,形成$M$个俱乐部。每个俱乐部里的学生有着一定相似的兴趣爱好,形成一个朋友圈。一个学生可以同时属于若干个不同的俱乐部。根据“我的朋友的朋友也是我的朋友”这个推论可以得出,如果A和B是朋友,且B和C是朋友,则A和C也是朋友。请编写程序计算最大朋友圈中有多少人。

输入格式:

输入的第一行包含两个正整数$N$(≤30000)和$M$(≤1000),分别代表学校的学生总数和俱乐部的个数。后面的$M$行每行按以下格式给出1个俱乐部的信息,其中学生从1~$N$编号:

1
第i个俱乐部的人数Mi(空格)学生1(空格)学生2 … 学生Mi

输出格式:

输出给出一个整数,表示在最大朋友圈中有多少人。

输入样例:

1
2
3
4
5
7 4
3 1 2 3
2 1 4
3 5 6 7
1 6

输出样例:

1
4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void Union( int x,int y);
int Find( int x);

int n,m;
int bcj[30005];

int main()
{
int i;
int n1;
int x,y;
int ans = 0;
scanf("%d %d",&n,&m);
for( i=1; i<=n; i++) bcj[i] = -1; //初始化并查集

while( m-- )
{
scanf("%d",&n1);
for( i=1; i<=n1; i++)
{
if( i==1 )
{
scanf("%d",&x);
}
else
{
scanf("%d",&y);
Union(x,y);
}
}
}
for( i=1; i<=n; i++)
{
if( bcj[i]<ans ) ans = bcj[i]; //负数需寻找最小的值
}
ans = 0-ans; //用负数表示集合中元素的个数
printf("%d",ans);
return 0;
}

//以下是并查集的两个基本操作
int Find( int x)
{
if(bcj[x]<0) return x;
return bcj[x] = Find(bcj[x]);
}

void Union( int x, int y)
{
x = Find(x);
y = Find(y);

if( x==y ) return;
bcj[x] += bcj[y];
bcj[y] = x;
}
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×