解题思路:硬写有两个超时点
#include<bits/stdc++.h>
using namespace std;
int father[100001];
int find(int x){
int j=-1;
while(x!=father[x]){
x=father[x];
j++;
}
return j;
}
void uniont(int a,int b){
father[b]=a;
}
int main(){
int n,fid,count=0,max=-1;
scanf("%d",&n);
for(int i=0;i<n+1;i++)
father[i]=i;
for(int i=1;i<=n;i++){
scanf("%d",&fid);
uniont(fid,i);
}
for(int i=1;i<=n;i++){
if(find(i)>max)
max=find(i);
}
cout<<max<<endl;
for(int i=1;i<=n;i++){
if(find(i)==max){
if(count==0){
cout<<i;
count++;
}
else
cout<<" "<<i;
}
}
}
运行结果:
![](https://img-blog.csdnimg.cn/4eb0ef972bee47bb843e0ceba6bdc4db.png)
后来转化了一下思路,在用find查找最小辈分的时候,就把每代人的辈分直接存储起来,这样就不会超时
#include<bits/stdc++.h>
using namespace std;
int father[100001];
int beifen[100001]={0};
int find(int x){
if(father[x]==-1)
beifen[x]=1;
if(beifen[x]==0)
beifen[x] = find(father[x])+1;
return beifen[x];
}
int main(){
int n,fid,count=0,max=-1;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&father[i]);
for(int i=1;i<=n;i++)
beifen[i]=find(i);
for(int i=1;i<=n;i++){
if(beifen[i]>max)
max=beifen[i];
}
cout<<max<<endl;
for(int i=1;i<=n;i++){
if(beifen[i]==max){
if(count==0){
cout<<i;
count++;
}
else
cout<<" "<<i;
}
}
}