GPLT L2-024 部落 (并查集)

N ≤ 104,输入如下数据如果没有路径压缩可能会超时。

10000

2 1 2

2 3 4

2 5 6

……

2 9997 9998

2 9999 10000

2 9999 9997

……

2 5 3

2 3 1

10000

10000 10000

……

10000 10000

但事实上,两种写法的运行时间都为 50ms 左右。

${O_{left( n^2/2 ight)}}$:

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

const int M=11000;

int fri[M];
bool vis[M];

int Find(int x){
    while(x!=fri[x]) x=fri[x];
    return x;
}

void Union(int A,int B){
    int friA=Find(A);
    int friB=Find(B);
    if(friA>friB) fri[friA]=friB;
    if(friB>friA) fri[friB]=friA;
}

int main()
{
    for(int i=0;i<M;i++) fri[i]=i;
    int n;cin>>n;
    for(int i=0;i<n;i++){
        int k;cin>>k;
        int a[k];
        for(int j=0;j<k;j++){
            cin>>a[j];
            vis[a[j]]=true;
            if(j) Union(a[j],a[j-1]);
        }
    }
    int people=0,tribe=0;
    for(int i=0;i<M;i++){
        if(vis[i]) ++people;
        if(vis[i]&&fri[i]==i) ++tribe;
    }
    cout<<people<<" "<<tribe<<"
";
    int q;cin>>q;
    for(int i=0;i<q;i++){
        int a,b;cin>>a>>b;
        cout<<(Find(a)==Find(b)?"Y":"N")<<"
";
    }
    return 0;
}

${O_{left( n ight)}}$:

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

const int M=11000;

int fri[M];
bool vis[M];

int Find(int x){
    int f=x;
    while(f!=fri[f]) f=fri[f];
    int a=x,b;
    while(a!=fri[a]) b=fri[a],fri[a]=f,a=b; 
    return f;
}

void Union(int A,int B){
    int friA=Find(A);
    int friB=Find(B);
    if(friA>friB) fri[friA]=friB;
    if(friB>friA) fri[friB]=friA;
}

int main()
{
    for(int i=0;i<M;i++) fri[i]=i;
    int n;cin>>n;
    for(int i=0;i<n;i++){
        int k;cin>>k;
        int a[k];
        for(int j=0;j<k;j++){
            cin>>a[j];
            vis[a[j]]=true;
            if(j) Union(a[j],a[j-1]);
        }
    }
    int people=0,tribe=0;
    for(int i=0;i<M;i++){
        if(vis[i]) ++people;
        if(vis[i]&&fri[i]==i) ++tribe;
    }
    cout<<people<<" "<<tribe<<"
";
    int q;cin>>q;
    for(int i=0;i<q;i++){
        int a,b;cin>>a>>b;
        cout<<(Find(a)==Find(b)?"Y":"N")<<"
";
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Kanoon/p/12509866.html