GPLT L2-024 部落 (并查集)

Posted kanoon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GPLT L2-024 部落 (并查集)相关的知识,希望对你有一定的参考价值。

 

Tips:

这种数据如果没有路径压缩的话是很容易超时的。

5001

2 1 2

2 3 4

2 5 6

……

2 9997 9998

2 9999 10000

5000 1 3 5 …… 9997 9999

10000

10000 10000

……

10000 10000

${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;
}

 事实上,二者的运行时间都为 50ms 左右。

以上是关于GPLT L2-024 部落 (并查集)的主要内容,如果未能解决你的问题,请参考以下文章

团体天梯练习 L2-024 部落

L2-024 部落 (25分)

L2-024. 部落

BZOJ 1821 部落划分(二分+并查集)

C++之路进阶——并查集(部落划分)

1821. [JSOI2010]部落划分并查集+二分