pat甲级 1118 Birds in Forest (25分)
note:并查集+路径压缩
#include <iostream>
#include <unordered_set>
using namespace std;
int pre[10005],isRoot[10005]={0};
unordered_set<int> s;//去重不排序,节省运行时间
int findpre(int x)
{
int a=x;
while(x!=pre[x]) x=pre[x];
//路径压缩
while(a!=pre[a])
{
int z=a;
a=pre[a];
pre[z]=x;
}
return x;
}
void Union(int a,int b)
{
int A=findpre(a);
int B=findpre(b);
if(A!=B) pre[B]=A;
}
int main()
{
int n,k,id,temp,q,tree=0;
cin>>n;
for(int i=0;i<10005;++i) pre[i]=i;//预处理
for(int i=0;i<n;++i)
{
cin>>k;
for(int j=0;j<k;++j)
{
cin>>id;
if(!j) temp=id;
else Union(temp,id);//合并
s.insert(id);
}
}
for(auto i:s)
{
int t=findpre(i);//避免重复运算,降低运行时间
if(!isRoot[t]) ++tree;
++isRoot[t];
}
cout<<tree<<' '<<s.size()<<endl;
cin>>q;
for(int i=0;i<q;++i)
{
cin>>id>>temp;
printf("%s\n",findpre(id)==findpre(temp)?"Yes":"No");
}
return 0;
}