某学校有 N 个学生,形成 M 个俱乐部。每个俱乐部里的学生有着一定相似的兴趣爱好,形成一个朋友圈。一个学生可以同时属于若干个不同的俱乐部。根据 “我的朋友的朋友也是我的朋友” 这个推论可以得出,如果 A 和 B 是朋友,且 B 和 C 是朋友,则 A 和 C 也是朋友。请编写程序计算最大朋友圈中有多少人。
输入格式
输入的第一行包含两个正整数 N(≤30000)和 M(≤1000),分别代表学校的学生总数和俱乐部的个数。后面的 M 行每行按以下格式给出 1 个俱乐部的信息,其中学生从 1~N 编号:
第 i 个俱乐部的人数 Mi(空格)学生 1(空格)学生 2 … 学生 Mi
输出格式
输出给出一个整数,表示在最大朋友圈中有多少人。
输入样例
1 | 7 4 |
输出样例
1 | 4 |
一些限制
项目 | 限制 |
---|---|
代码长度限制 | 16 KB |
时间限制 | 400 ms |
内存限制 | 64 MB |
栈限制 | 8192 KB |
解题思路
- 初始化
init
1
2
3
4
5void init(int n) {
for(int i = 1; i <= n; ++i) {
fa[i] = i;
}
} - 查询
find
1
2
3
4
5
6
7int find(int i) {
if(i == fa[i]) return i;
else {
fa[i] = find(fa[i]);
return fa[i];
}
} - 合并
unionn
1
2
3
4void union1(int a, int b) {
int afa = find(a), bfa = find(b);
fa[afa] = bfa;
} - 更新
update
(这个是我写题时想到的)1
2
3
4
5
6
7int update(int i) {
if(i == fa[i]) return i;
else {
fa[i] = find(fa[i]);
return fa[i];
}
} - 最后的数据整理工作(如统计最大的人数等)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15unordered_map<int, int> mp;
for(int i = 1; i <= N; ++i) {
update(i);
}
for(int i = 1; i <= N; ++i) {
if(mp.find(fa[i]) != mp.end()) {
mp[fa[i]] += 1;
} else {
mp[fa[i]] = 1;
}
}
for(auto i: mp) {
maxCount = max(maxCount, i.second);
}
cout << maxCount;
Code
1 |
|