Gym - 102770I
Gym - 102770I
题解:并查集+离散化+map
首先题目确保每双袜子都是成对的,我们很容易发现袜子之间存在限制条件比如
1 2
2 3
1 3
所以我们往建图方面想,这样每一个关系都代表了一个连通块,我们只要找到哪个连通块里面点数最多不就好了,点数我们可以用map,或者szp数组来求,但是这里感觉map方便一点,map直接对根节点计数就好了,然后最后答案/2,因为答案让你给出袜子的对数,但是真就这么简单嘛?我们看到\(a^i,b^i\)数据范围都在\(1e9\),说明fa[x]数组开不了那么大,所以我们直接选择离散化
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 1e5 + 10;
int fa[N];
int n, m;
void init()
{
for (int i = 1; i <= n; ++i)
fa[i] = i;
}
int find(int x)
{
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y)
{
int fx = find(x);
int fy = find(y);
fa[fy] = fx;
}
ll a[N];
ll b[N];
map<ll, ll> mp;
vector<ll> v;
int main(void)
{
Zeoy;
int t = 1;
cin >> t;
while (t--)
{
mp.clear();
v.clear();
cin >> n;
v.push_back(0);
init();
for (int i = 1; i <= n; ++i)
{
cin >> a[i] >> b[i];
v.push_back(a[i]);
v.push_back(b[i]);
}
sort(v.begin() + 1, v.end());
v.erase(unique(v.begin() + 1, v.end()), v.end());
for (int i = 1; i <= n; ++i)
{
a[i] = lower_bound(v.begin() + 1, v.end(), a[i]) - v.begin();
b[i] = lower_bound(v.begin() + 1, v.end(), b[i]) - v.begin();
merge(a[i], b[i]);
}
ll ans = -1;
for (int i = 1; i <= n; ++i)
{
ll root1 = find(a[i]);
ll root2 = find(b[i]);
mp[root1]++;
mp[root2]++;
ans = max({mp[root1], mp[root2], ans});
}
cout << ans / 2 << endl;
}
return 0;
}