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;
}
posted @ 2023-01-08 23:07  Zeoy_kkk  阅读(22)  评论(0编辑  收藏  举报