给定多张照片,在同一张照片里的鸟认为它们在一棵树上。打印树的最大可能数量和鸟的个数。
并查集,先将每个节点的父节点指向自己,然后将一棵树上的鸟的父节点都指向第一只鸟的父节点。记录鸟编号的最大数作为鸟的只数(因为说明了鸟的编号是从1-n)。然后计算树的个数(就是父节点个数),排序后有几个连续的true就有几棵树。
#include <bits/stdc++.h>
using namespace std;
int n,m,query,sumtime=0;
int father[10010];
bool tree[10010];
int findFather(int x){
int a=x;
while(x!=father[x]) x=father[x];
while(a!=father[a]){
int z=a;
a=father[a];
father[z]=x;
}
return x;
}
void Union(int a,int b){
int fathera=findFather(a);
int fatherb=findFather(b);
if(fathera!=fatherb)father[fathera]=fatherb;
}
int main(){
for(int i=0;i<10010;i++)father[i]=i;
scanf("%d",&n);
int maxbirdid=-1,treenum=0;
for(int i=0;i<n;i++){
int num;
scanf("%d",&num);
int firstid;
for(int j=0;j<num;j++){
int id;
scanf("%d",&id);
if(j==0)firstid=id;
if(id>maxbirdid)maxbirdid=id;
Union(id,firstid);
}
}
for(int i=1;i<=maxbirdid;i++){
findFather(i);
tree[father[i]]=true;
}
sort(tree,tree+10010);
while(tree[10009-treenum])treenum++;
printf("%d %d\n",treenum,maxbirdid);
scanf("%d",&query);
for(int i=0;i<query;i++){
int a,b;
scanf("%d%d",&a,&b);
if(father[a]==father[b])printf("Yes\n");
else printf("No\n");
}
}