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 部落 (并查集)的主要内容,如果未能解决你的问题,请参考以下文章