并查集解法
- 借鉴了 @onestan 的并查集解法,封装成类,方便阅读
- 不懂并查集可以看 B 站宝藏 UP 主 @正月点灯笼 的视频讲解:并查集
#include <bits/stdc++.h>
using namespace std;
class friendsCircle
{
private:
// curMap记录父节点,sizeMap记录该点所在朋友圈的大小,rankMap记录根节点的秩
unordered_map<int,int> curMap, sizeMap, rankMap;
private:
// 寻找根节点
int findroot(int son)
{
while ( curMap[son]!=son ) son = curMap[son];
return son;
}
public:
// 向朋友圈中插入新的朋友组合
void append(int x, int y)
{
if ( curMap.find(x)==curMap.end() && curMap.find(y)==curMap.end() )
{
// 若插入的两点都不在朋友圈中
curMap[x] = x; // 更新 x 为父节点
curMap[y] = x; // 更新 y 为 x 的子节点
rankMap[x] = 1; // 更新 x 的秩
}
else if ( curMap.find(x)!=curMap.end() && curMap.find(y)==curMap.end() )
{
// 若 x 在朋友圈中, y 不在朋友圈中,将 y 更新为 x 根节点的子节点
int xroot = findroot(x);
curMap[y] = xroot;
}
else if ( curMap.find(x)==curMap.end() && curMap.find(y)!=curMap.end() )
{
// 若 y 在朋友圈中, x 不在朋友圈中,将 x 更新为 y 根节点的子节点
int yroot = findroot(y);
curMap[x] = yroot;
}
else
{
// 若 x 和 y 都在朋友圈中,根据他们根节点的秩对两个朋友圈融合
int xroot = findroot(x);
int yroot = findroot(y);
if ( rankMap[xroot]>=rankMap[yroot] )
{
curMap[yroot] = xroot;
rankMap[xroot] = max(rankMap[xroot], rankMap[yroot]+1);
}
else
{
curMap[xroot] = yroot;
}
}
}
// 计算最大朋友圈的大小
int maxCircle()
{
int maxSize = 0;
for (auto & it : curMap)
maxSize = max(maxSize, ++sizeMap[findroot(it.first)]);
return maxSize;
}
};
int main()
{
int T, n;
cin >> T;
while ( T-- )
{
cin >> n;
friendsCircle FRDC;
int x, y;
while ( n-- )
{
cin >> x >> y;
FRDC.append(x,y);
}
cout << FRDC.maxCircle() << endl;
}
return 0;
}