题解 | 旺仔哥哥走迷宫

旺仔哥哥走迷宫

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

全部评论

相关推荐

LZHR:老哥你从投递简历测评完到一面中间隔了多久呀,我这边已经过了五天了仍显示简历筛选中是不是就是挂了
腾讯求职进展汇总
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务