题目描述
班里 NN 个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。
在一个游戏中,需要小朋友坐一个圈,每个小朋友都有自己最崇拜的小朋友在他的右手边。
求满足条件的圈最大多少人?
小朋友编号为 1,2,3,\cdots N1,2,3,⋯N。
输入描述
输入第一行,一个整数 N(3<N<10^5)N(3<N<105)。
接下来一行 NN 个整数,由空格分开。
输出描述
要求输出一个整数,表示满足条件的最大圈的人数。
样例">样例">样例">输入输出样例
示例
输入
9
3 4 2 5 3 8 4 6 9
输出
4
样例解释
如下图所示,崇拜关系用箭头表示,红色表示不在圈中。
显然,最大圈是[2 4 5 3] 构成的圈。
思路:很明显,这种题要进入逐步进入一个个节点,想到DFS和图,根据题意只有一个出度,多个入度。我刚开始想的是使用一个邻接矩阵去存储,但是在实际应用中发现,我们不需要去管理入度,只需要去看出度指向的是谁就可以,同时邻接矩阵中存储的只是1和0的话对内存会有比较大的浪费(怕爆内存哈哈哈),我就想着能不能优化成一维数组,数组下标表示小朋友的位置,数组存储小朋友崇拜的人的下标。最开始我想的是只遍历一次,就去判断有多少个环,以及环的最大值,但是我写的时候发现思路断了,我不知道一次遍历怎么去判断形成了环之后这个环的长度。无奈,我参考了一下这个老哥的思路,遍历每一个小孩,找到该小孩所在的最大环的长度。
参考:(27条消息) 小朋友崇拜圈(DFS)_这咋又bug了嘛的博客-CSDN博客
贴上代码
import java.util.Arrays;
import java.util.Scanner;
public class Main{
static int a[];
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n= input.nextInt();
a=new int[n+1];
int max=0;
for(int i=1;i<=n;i++){//数组存储里面指向下一个目标的下标。
a[i]=input.nextInt();
}
for(int i=1;i<=n;i++){
max=Math.max(DFS(a[i],i,1), max);
}
System.out.println(max);
}
static int DFS(int x,int xn,int l){
int res=l;
if(x==xn){
return res;
}
if(l>a.length){//没有形成环
return 0;
}
res=DFS(a[x],xn,++l);
return res;
}
}