dfs加标记数组
总体思路使用dfs进行暴搜,标记数组标记已经成环或者从未成环的节点。如果任一节点的下个节点已经成环则进行剪枝操作
import java.util.Scanner;
public class Main {
static int n;
static int[] nums;
static boolean[] flags;
static int temp, max, st;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
nums = new int[n + 10];
flags = new boolean[n + 10];
for (int i = 1; i <= n; i++) {
nums[i] = sc.nextInt();
}
sc.close();
//将被崇拜节点标记
for (int i = 1; i <= n; i++) {
flags[nums[i]] = true;
}
for (int i = 1; i <= n; i++) {
//若当前节点没有崇拜者,不可能在环中,continue
if (flags[nums[i]] == false) {
continue;
}
//st记录初始节点值
st = i;
//temp为当前最大值,初始化
temp = 1;
dfs(1, i);
}
System.out.println(max);
}
public static void dfs(int i, int index) {
//如果环中节点个数大于最大数,则直接返回
if (i > n) {
return;
}
//如果下一节点是已经成环的节点,剪枝
if(flags[index] == false)
return;
//如果下一节点(当前节点)与初始节点相同,则表示成环
if (st == nums[index]) {
//更新最大值
if (max < temp) {
max = temp;
}
//对该换所有节点进行标记,如果其他节点的下一个节点为该环的任一节点,直接返回
int x = nums[st];
int count = 1;
while(count <= temp){
flags[x] = false;
x = nums[x];
count++;
}
return;
}
//当前记录值加1
temp++;
int x = nums[index];
//递归
dfs(i + 1, x);
}
}
这太强了
强啊,华哥