C++代码实现 小计是一个程序员,他为学校做了一个校园聊天系统,已知系统中有 n 名用户,编号为 1~n,现在已知有 m 对好友关系,每一对关系由两个整数 x 和 y 组成 ,表示编号为 x 的用户和编号为 y 的用户是一对好友,请问校园中有多少个圈子,人数最多的圈子有多少人。 圈子:一个圈子中的人一定直接与同圈子的其他人是好友,或者通过若干名同圈子的人,间接与同圈子的其他人是好友。 小计是一个程序员,他为学校做了一个校园聊天系统,已知系统中有 n 名用户,编号为 1~n,现在已知有 m 对好友关系,每一对关系由两个整数 x 和 y 组成 ,表示编号为 x 的用户和编号为 y 的用户是一对好友,请问校园中有多少个圈子,人数最多的圈子有多少人。 圈子:一个圈子中的人一定直接与同圈子的其他人是好友,或者通过若干名同圈子的人,间接与同圈子的其他人是好友。
时间: 2023-11-27 09:55:37 浏览: 178
以下是C++代码实现:
```cpp
#include <iostream>
#include <vector>
using namespace std;
const int MAXN = 1005;
int n, m;
int fa[MAXN], size[MAXN];
void init() {
for (int i = 1; i <= n; i++) {
fa[i] = i;
size[i] = 1;
}
}
int find(int x) {
if (fa[x] == x)
return x;
return fa[x] = find(fa[x]);
}
void unite(int x, int y) {
int fx = find(x), fy = find(y);
if (fx == fy)
return;
if (size[fx] < size[fy])
swap(fx, fy);
fa[fy] = fx;
size[fx] += size[fy];
}
int main() {
cin >> n >> m;
init();
for (int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
unite(x, y);
}
int cnt = 0, max_size = 0;
for (int i = 1; i <= n; i++) {
if (fa[i] == i)
cnt++;
max_size = max(max_size, size[i]);
}
cout << cnt << endl;
cout << max_size << endl;
return 0;
}
```
思路解析:
题目要求我们求出圈子的个数和人数最多的圈子的人数,这是一道典型的并查集问题。
首先使用 `init()` 函数初始化每个节点的父节点为自己,大小为1。接下来遍历所有的好友关系,使用 `unite()` 函数将两个好友所在的集合合并。最后遍历所有的节点,统计圈子的个数和人数最多的圈子的人数。
其中,`find()` 函数用于查找一个节点所在的集合,使用路径压缩优化可以提高效率。`unite()` 函数用于合并两个集合,按秩合并可以保证并查集的效率。
时间复杂度分析:使用路径压缩和按秩合并优化后,每次操作的时间复杂度为 O(logn),总共有 m 次操作,所以总时间复杂度为 O(mlogn)。空间复杂度为 O(n)。
阅读全文