[cf] Invoking the Magic

题意后面在来补充

离散化+并查集

虽然我现在还是没太明白为什么用并查集,我觉得就是当find(a) == find(b)的时候就相当于是有个环了,就可以清空了。

对于离散化我现在还有点不清楚,上次看了y总的板子也没有深入理解先在复习下离散化的知识

离散化

步骤

  1. 排序
  2. 去重
  3. 二分索引
vector<int> alls; // 存储所有待离散化的值
sort(alls.begin(), alls.end()); // 将所有值排序
alls.erase(unique(alls.begin(), alls.end()), alls.end());   // 去掉重复元素

// 二分求出x对应的离散化的值
int find(int x) // 找到第一个大于等于x的位置
{
    int l = 0, r = alls.size() - 1;
    while (l < r)
    {
        int mid = l + r >> 1;
        if (alls[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return r + 1; // 映射到1, 2, ...n
}

写了很久,还是没过,有点难受,不知道是哪里错了,但是思路是这个思路等以后再看,重新写一遍把,代码先放在这里

#include <bits/stdc++.h>
using namespace std;
///Invoking the Magic

const int N = 1e5 +10;
int a[N];///原数组
int b[N];///原数组


int d[N];///并查集
int cnt[N];
vector<int> v;


void file()
{
#ifdef ONLINE_JUDGE
#else
    freopen("D:/workProgram/test.txt","r",stdin);
    //freopen("D:/LSNU/codeforces/duipai/WA.txt","w",stdout);
#endif
}


int Find(int x)
{
    int l = 0, r = v.size() - 1;
    while( l < r ){
        int mid = (l + r ) >> 1;
        if( v[mid] >= x ) r = mid;
        else l = mid + 1;
    }
    return r;
}

int Search(int x)
{
    if(d[x] != x) d[x] = Search(d[x]);
    return d[x];
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    file();
    int n ;
    cin >> n;
    while(n--){
        int m;
        cin >> m;
        ///离散化
        for(int i = 0; i < m ; i++){
            cin >> a[i] >> b[i];
            v.push_back(a[i]);
            v.push_back(b[i]);
        }

        sort(v.begin(),v.end());
        v.erase( unique(v.begin(),v.end()) , v.end());
//        cout << v.size();
//        for(int i = 0 ; i < v.size() ; i++){
//            cout << v[i] << endl;
//        }
        for(int i = 0 ;i < m ; i++){
            d[i] = i;
            cnt[i] = 1;
        }

        ///并查集
        for(int i = 0 ; i < m; i++){
            a[i] = Find(a[i]);
            b[i] = Find(b[i]);
            //cout << a[i] << " " << b[i] << endl;
        }

        int ans = 0;
        for(int i = 0; i < m ;i++){
            int fa = Search(a[i]);
            int fb = Search(b[i]);

            if(fa != fb){
                d[fa] = fb;
                cnt[fb] += cnt[fa];
                ans = max( ans,cnt[fb] );
            }
        }

        cout << ans << endl;
    }
    return 0;
}

posted @ 2020-11-23 01:21  Hoppz  阅读(119)  评论(0编辑  收藏  举报