- 使用并查集,来记录所有人的关系
- 再将每个人的顶送入set中,set的长度就是班级数量
- 再用一个循环找到最大班级即可
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int st[N], f[N], s[N], n, m;
set<int> ss;
void init(int n) {
for (int i = 1; i < n; i++) { // 初始化
f[i] = i;
s[i] = 1;
}
}
int find(int i) {
int size = 0; // 沿途收集了几个点
while (i != f[i]) { // 还没有到顶
st[size++] = i; // 收集沿途上的所有点
i = f[i]; // 向上查询是否到顶
}
while (size > 0) {
f[st[--size]] = i; // 扁平化
}
return i; // 返回父节点
}
bool isSameSet(int x, int y) {
return find(x) == find(y);
}
void merge(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return ; // 顶相同说明是同一个集合,可以不用合并了
if (s[fx] > s[fy]) { // fx > fy 小挂大
s[fx] += s[fy];
f[fy] = fx;
} else {
s[fy] += s[fx];
f[fx] = fy;
}
}
int main() {
cin >> n >> m;
init(n + 1); // 初始化
for (int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
merge(x, y); // 合并两个集合
}
for (int i = 1; i <= n; i++) {
ss.insert(find(i)); // 使用set得到有多少个不同的顶的数量
}
int val = 0;
for (auto it : ss) {
val = max(val, s[it]);
}
cout << ss.size() << ' ' << val << '\n';
return 0;
}