小朋友崇拜圈(DFS)

班里 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;
}
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这咋又bug了嘛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值