大致意思: 有多组输入,每组输入第一行为袜子种类n(也是接下来需要输入的数对数量),接下来输入n组数对,找出哪几个数对组合在一起恰能使袜子两两配对,输出组合中袜子种类最多的那一组有几种袜子。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
const int N = 1e5 + 7;
int Fa[N], sz[N];
map<int, int>mp;
int total;
int find(int x) {
if (Fa[x] == x)return x;
else return Fa[x] = find(Fa[x]);
}
void merge(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx != fy) {
Fa[fx] = fy;
sz[fy] += sz[fx];
}
}//find和merge是并查集的模板详细可见上一篇博客
int get(int x) {
if (mp.count(x))return mp[x];
else mp[x] = ++total;
return mp[x];
}//因为数据最大为2^30不能作为Fa数组的下标,get函数的作用是把大数化小.
//例如第一个数据是x=1234567则get(x)=1,第二个数据是y=79836598947593则get(y)=2以此类推……
int T, n;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> T;
while (T--) {
cin >> n;
mp.clear();
total = 0;//别忘了初始化total的值
for (int i = 1; i <=n; i++) {
Fa[i] = i;
sz[i] = 1;
}
int x, y;
for (int i = 1; i <= n; i++) {
cin >> x >> y;
x = get(x), y = get(y);//利用get函数将大数变小,从而将1e9的大小变成1e5的大小,使得Fa[]能够容纳
merge(x, y);
}
int ans = 0;
for (int i = 1; i <=n; i++) {
ans = max(ans, sz[find(i)]);//寻找元素最多的树
}
cout << ans << '\n';
}
return 0;
}
//当需要初始化的量比较多的时候可以用一个函数进行初始化如下函数
/*void inta() {
mp.clear();
total = 0;
for (int i = 1; i <= n; i++) {
Fa[i] = i;
sz[i] = 1;
}
}*/