1 条题解

  • 0
    @ 2025-7-2 23:21:02

    JAVA题解:

    import java.util.*;
    
    public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int N = sc.nextInt();
            
            // 读取距离矩阵
            int[][] g = new int[N][N];
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    g[i][j] = sc.nextInt();
                }
            }
            
            // 读取入口/出口信息
            int[] isEntrance = new int[N];
            for (int i = 0; i < N; i++) {
                isEntrance[i] = sc.nextInt();
            }
            
            // 读取起点和终点
            int S = sc.nextInt(), T = sc.nextInt();
            
            // 计算最短路径
            List<Integer> result = findShortestPath(N, g, isEntrance, S, T);
            
            // 输出结果
            for (int i = 0; i < result.size(); i++) {
                if (i > 0) System.out.print(" ");
                System.out.print(result.get(i));
            }
        }
        
        /**
         * 寻找从起点到终点的最短路径
         */
        private static List<Integer> findShortestPath(int N, int[][] g, int[] isEntrance, int S, int T) {
            final int INF = Integer.MAX_VALUE / 2;
            int[] dist = new int[N];
            List<List<Integer>> paths = new ArrayList<>();
            
            // 初始化距离和路径
            for (int i = 0; i < N; i++) {
                dist[i] = INF;
                paths.add(new ArrayList<>());
            }
            
            // 设置起点
            dist[S] = 0;
            paths.get(S).add(S);
            
            // 优先队列,按 (距离, 节点) 升序排列
            PriorityQueue<int[]> pq = new PriorityQueue<>(
                Comparator.<int[]>comparingInt(a -> a[0])
                          .thenComparingInt(a -> a[1])
            );
            pq.offer(new int[]{0, S});
            
            while (!pq.isEmpty()) {
                int[] cur = pq.poll();
                int d = cur[0], u = cur[1];
                
                // 如果当前距离大于已知最短距离,跳过
                if (d > dist[u]) continue;
                
                // 遍历所有可能的下一个节点
                for (int v = 0; v < N; v++) {
                    if (g[u][v] == 0) continue; // 不相邻
                    
                    int nd = d + g[u][v];
                    List<Integer> newPath = new ArrayList<>(paths.get(u));
                    newPath.add(v);
                    
                    // 如果找到更短的路径,或者距离相同但字典序更小
                    if (nd < dist[v] || (nd == dist[v] && lexLess(newPath, paths.get(v)))) {
                        dist[v] = nd;
                        paths.set(v, newPath);
                        pq.offer(new int[]{nd, v});
                    }
                }
            }
            
            return paths.get(T);
        }
        
        /**
         * 比较两条路径的字典序
         * @return true if path a is lexicographically smaller than path b
         */
        private static boolean lexLess(List<Integer> a, List<Integer> b) {
            int n = Math.min(a.size(), b.size());
            for (int i = 0; i < n; i++) {
                if (!a.get(i).equals(b.get(i))) {
                    return a.get(i) < b.get(i);
                }
            }
            return a.size() < b.size();
        }
    }
    
    
    
    • 1

    信息

    ID
    16
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    4
    已通过
    1
    上传者