之前看柳婼学姐PAT经验集,觉得她讲输出的时候一定要注意,特别是大小写,我还不以为意,觉得这个没什么,今天就踩雷了…一直答案错误,还好最后看出来大小写的问题。所以大家在刷题和考试的时候千万注意啊…
思路:
1.由于鸟的index是连续的,因此我们记录遇到的最大的编号,就是鸟的数量;
2.使用并查集算法,遍历数组,记录最后编号和自己一样的鸟的数量,即树的数量;
3.每遇到两个鸟,去寻找他们的上级,直到上级是自己,比较这两个上级是否相同,相同则在同一颗树,否则不在同一颗树;
PS:我的代码可以继续优化效率:每次查找,更新自己的上级为最后寻找到的上级,多次查找后效率会明显提高;(但是我懒得加了,喜欢短代码)
代码:
#include<iostream>
using namespace std;
int bird[10005];
int main(){
for(int i=1;i<=10000;i++) bird[i]=i;
int n,q,cnt=0,num=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
int k,temp=0,id,a,b;
scanf("%d",&k);
for(int j=0;j<k;j++){
scanf("%d",&id);
num=max(num,id);
for(a=temp;bird[a]!=a;a=bird[a]);
for(b=id;bird[b]!=b;b=bird[b]);
if(j) a<b?bird[b]=a:bird[a]=b;
temp=id;
}
}
for(int i=1;i<=num;i++)
if(bird[i]==i) cnt++;
printf("%d %d
",cnt,num);
scanf("%d",&q);
for(int i=0;i<q;i++){
int b1,b2,a,b;
scanf("%d%d",&b1,&b2);
for(a=b1;bird[a]!=a;a=bird[a]);
for(b=b2;bird[b]!=b;b=bird[b]);
printf(a==b?"Yes
":"No
");
}
return 0;
}