班里 NN 个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。
在一个游戏中,需要小朋友坐一个圈,每个小朋友都有自己最崇拜的小朋友在他的右手边。
求满足条件的圈最大多少人?
小朋友编号为 1,2,3,\cdots N1,2,3,⋯N。
输入描述
输入第一行,一个整数 N(3<N<10^5)N(3<N<10
5
)。
接下来一行 NN 个整数,由空格分开。
输出描述
要求输出一个整数,表示满足条件的最大圈的人数。
思路:如图可见是让我们求一个最大的圈,题目可知每个点最多只有一个入度一个出度,所以是找一个最大的有向连通图,我们可以用DFS来解决这个问题,每次将循环搜索传入当前小朋友崇拜的人和他自己,然后DFS内如果x的崇拜对象就是我们刚开始传进去的ll,那么这个连通图的最大范围就在cnt里了,我们更新cnt,然后return,记得一定要return,不然会死循环,因为有的小朋友是没有人崇拜的他(好可怜)所以最终是不会回到他的位置,我们就要做一个判断,如果搜索过了所有的小朋友,我们就结束循环。
上代码:
#include<bits/stdc++.h>
using namespace std;
int n,cnt,ans;
int a[100005];
void dfs(int x,int ll,int cnt){
if(cnt>n)return; //如果所有小朋友都搜索了,返回
if(x==ll){ //如果搜到了第一个传进来的小朋友,这个有向连通图就全部找完了
ans=max(ans,cnt); //更新答案
return; //记得一定return,不然死循环(虽然第一个return已经阻止了死循环,但答案肯定是错的)
}
dfs(a[x],ll,cnt+1); //搜索当前小朋友的崇拜对象
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
dfs(a[i],i,1); //搜索每个小朋友崇拜的对象,并传入这个小朋友的编号
}
cout<<ans;
return 0;
}