深搜题目——小朋友的崇拜圈


题目

题目描述

班里 N 个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。

在一个游戏中,需要小朋友坐一个圈,每个小朋友都有自己最崇拜的小朋友在他的右手边。

求满足条件的圈最大多少人?

小朋友编号为 1,2,3,⋯N。

输入描述

输入第一行,一个整数 N(3<N<10^5)。

接下来一行 N 个整数,由空格分开。

输出描述

要求输出一个整数,表示满足条件的最大圈的人数。

解题思路

将样例的转换一下:


其实这道题就可以看成一个在图中求路径最长的环的长度; 因此这道题就可以用DFS直接解决了;

每个节点用s[]存储,ne[]存储第i个节点的后继节点。

首先遍历每个节点,然后根据题目要求可以得知我们有以下限制条件:1.最后找到的要是环,则最后ne[]要等于i;2.如果没有找到,直接返回0即可;

#include <iostream>
using namespace std;
const int N = 1e5+10;
int ne[N],s[N];//存储节点信息
int tmp;//遍历的节点
int n;
int cnt;//计数
int m;//记录最后答案
int dfs(int i){
  if(ne[i]==0) return 0;//如果ne[]没有赋值则意味着无论如何也不会连
                        //成环直接返回0即可
  if(ne[i]==tmp){
    cnt++;
    return cnt;//如果找到了返回当前计数
  }
  cnt++;
  dfs(ne[i]);//搜索下一节点
  return cnt;
}
int main()
{
  scanf("%d",&n);
  for(int i=1;i<=n;i++) {
    s[i] = i;
    scanf("%d",&ne[i]);
  }
  for(int i=1;i<=n;i++){
    tmp = i;
    m = max(m,dfs(i));
    cnt = 0;//每次找完一个节点重新计数
  }
  printf("%d",m);
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值