题目:https://www.patest.cn/contests/pat-a-practise/1118
每行给了一棵树,树上有这么多鸟和其编号,问有多少颗树和几只鸟,以及两只鸟在不在一棵树上。
这道并查集其实很简单,circul别搞错就行
复制相似代码一定把变量改过来,尽量少偷懒
/*
并查集:一种树形结构,后存储数据,查找只需线性的复杂度
存的是鸟不是树
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=10005;
int ans[maxn]={0},father[maxn]={0};
int find(int x){ //查找并认爸爸
if(x!=father[x])
father[x]=find(father[x]);
return father[x];
}
void Union(int x,int y){ //x的爸爸是y
int a=find(x);
int b=find(y);
if(a==b)
return;
father[a]=b;
}
int main(){
int n,k,t,maxb=0,root;
cin>>n;
for(int i=1;i<maxn;i++)
father[i] = i;
for(int i=1;i<=n;i++){
cin>>k;
cin>>root;
if(root>maxb) //找共有多少鸟
maxb=root;
for(int j=1;j<k;j++){
cin>>t;
if(t>maxb)
maxb=t;
Union(root,t); //t必须是root的爸爸,顺序不能错
}
}
int cnt=0;
for(int i=1;i<=maxb;i++)
ans[find(i)]++; //把所有根节点都找出来
for(int i=1;i<=maxb;i++){
if(ans[i])
cnt++;
}
printf("%d %d\n",cnt,maxb);
int m;
cin>>m;
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
if(find(a)==find(b))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}