P3378 (模板)并查集

  使用带路径压缩的并查集,不然会TLE

  AC代码:

#include <bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define st first
#define nd second
#define rd third
#define rg register
#define FOR(i, a, b) for(int i =(a); i <=(b); ++i)
#define RE(i, n) FOR(i, 1, n)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define REP(i, n) for(int i = 0;i <(n); ++i)
#define VAR(v, i) __typeof(i) v=(i)
#define FORE(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
using namespace std;

const int N = 100010;
int id[N];
void init(int n)
{
    for (int i = 1; i <= n; i++)
        id[i] = i;
}
int sear(int p)
{
    while (id[p] != p)
        p = id[p];
    return p;
}
int tran(int i) // 路径压缩
{
    int r = sear(i);
    while (i != r)
    {
        int p = id[i];
        id[i] = r;
        i = p;
    }
    return r;
}
bool isun(int i, int j)
{
    return sear(i) == sear(j);
}
void unio(int i, int j)
{
    int p = tran(i), r = tran(j);
    if (p != r) id[p] = r;
}
int main()
{
    int n, m, k, opera;
    cin >> n >> m;
    init(n);
    while(m--)
    {
        cin >> opera;
        switch(opera)
        {
            case 1: cin >> k >> n; unio(k, n); break;
            case 2: cin >> k >> n; if(isun(k, n)) cout << 'Y' << endl; else cout << 'N' << endl; break;
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/darkchii/p/9676362.html