小朋友崇拜圈 JAVA DFS

题目描述

班里 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;
	}

}

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以使用以下代码实现 Java 中的 DFS 输出路径: ```java import java.util.*; public class Main { static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 上下左右四个方向 static int n, m; static int[][] matrix; static boolean[][] visited; static List<int[]> path = new ArrayList<>(); // 存储路径 public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); m = sc.nextInt(); matrix = new int[n][m]; visited = new boolean[n][m]; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { matrix[i][j] = sc.nextInt(); } } dfs(0, 0); } public static void dfs(int x, int y) { if (x < 0 || x >= n || y < 0 || y >= m || visited[x][y] || matrix[x][y] == 0) { return; } visited[x][y] = true; path.add(new int[]{x, y}); // 添加当前节点到路径中 if (x == n - 1 && y == m - 1) { // 到达终点,输出路径 for (int[] p : path) { System.out.print("(" + p[0] + "," + p[1] + ") "); } System.out.println(); } for (int[] dir : dirs) { int nx = x + dir[0]; int ny = y + dir[1]; dfs(nx, ny); } path.remove(path.size() - 1); // 回溯,从路径中删除当前节点 visited[x][y] = false; } } ``` 这段代码实现了一个简单的 DFS,用于输出从左上角到右下角的路径。其中 `matrix` 数组表示迷宫,0 表示障碍物,1 表示可以通过的路。`visited` 数组用于记录节点是否被访问过,`path` 列表用于存储路径。在 DFS 中,如果当前节点是终点,则输出路径;否则,遍历当前节点的四个方向,递归调用 DFS。在回溯时,从路径中删除当前节点,将当前节点标记为未访问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值