题解 | 旺仔哥哥走迷宫
旺仔哥哥走迷宫
https://www.nowcoder.com/practice/4b4ee516c23d4bd2b838646363b5c395
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
// 使用 BufferedReader 和 PrintWriter 提升大规模数据下的 I/O 效率
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
// 读取第一行输入,获取节点数n和边数m
String[] strA = br.readLine().trim().split("\\s+");
int n = Integer.parseInt(strA[0]); // 节点数量
int m = Integer.parseInt(strA[1]); // 边的数量
int[] t = new int[n + 1]; // 存储每个节点的类型,索引从1开始
// 读取第二行输入,获取每个节点的类型
String[] strB = br.readLine().trim().split("\\s+");
// 将节点类型数据存入数组t,索引从1开始
for (int i = 1; i <= n; i++) {
t[i] = Integer.parseInt(strB[i - 1]);
}
// 创建邻接表表示的图结构
List<Integer>[] adj = new ArrayList[n + 1];
for (int i = 1; i <= n; i++) {
adj[i] = new ArrayList<>();
}
// 读取所有边的信息,构建无向图
for (int i = 0; i < m; i++) {
String[] edge = br.readLine().trim().split("\\s+");
int u = Integer.parseInt(edge[0]); // 边的一个端点
int v = Integer.parseInt(edge[1]); // 边的另一个端点
adj[u].add(v); // 添加边到邻接表
adj[v].add(u); // 无向图,双向添加
}
// 检查起点或终点是否为类型1,如果是则直接输出"No"
if (t[1] == 1 || t[n] == 1) {
out.println("No");
} else {
// 调用BFS算法判断路径是否可行
if (bfs(n, adj, t)) {
out.println("Yes");
} else {
out.println("No");
}
}
// 刷新缓冲区确保数据完整写出并关闭流
out.flush();
out.close();
br.close();
}
/**
* 使用广度优先搜索(BFS)算法判断从节点1到节点n是否存在有效路径
*
* @param n 节点总数
* @param adj 邻接表,表示图的连接关系
* @param t 数组,标记节点的状态(0表示可通过,非0表示不可通过)
* @return 如果存在从节点1到节点n的有效路径则返回true,否则返回false
*/
private static boolean bfs(int n, List<Integer>[] adj, int[] t) {
// 创建队列用于BFS遍历
Queue<Integer> queue = new LinkedList<>();
// 创建访问标记数组,记录节点是否被访问过
boolean[] visited = new boolean[n + 1];
// 从节点1开始搜索
queue.add(1);
visited[1] = true;
// 当队列不为空时,继续搜索
while (!queue.isEmpty()) {
// 取出队首节点
int cur = queue.poll();
// 如果到达目标节点n,返回true
if (cur == n) {
return true;
}
// 遍历当前节点的所有邻接节点
for (int neighbor : adj[cur]) {
// 如果邻接节点可通过且未被访问过
if (t[neighbor] == 0 && !visited[neighbor]) {
// 标记为已访问并入队
visited[neighbor] = true;
queue.add(neighbor);
}
}
}
// 队列已空未到达目标节点,返回false
return false;
}
}
查看18道真题和解析