蓝桥杯-最短路

103 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述:

如下图所示,G是一个无向图,其中蓝色边的长度是 1、橘色边的长度是 2、绿色边的长度是 3

图片描述

则从 AS 的最短距离是多少?

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

二、思路分析:

这一题是经典的最短路问题,首先从图中可以看出图为疏密图,且权为正值,所以我们可以使用朴素dijkstar算法进行运算。

具体思想为:经历n次循环(n为节点数),每一次都找到未确定的离起点最近的未确定为最短路的节点。用这个节点更新其他节点的距离,然后标记为已确定。每次都可以确定最短路的一个节点。

三、AC 代码:


import java.util.Arrays;

// 1:无需package
// 2: 类名必须Main, 不可修改

public class zuiduanlu {
  public static int n = 19;
  public static int[][]g = new int[n][n];
  public static int[] dist = new int[n];
  public static boolean[] s = new boolean[n];
    public static void add(char a,char b,int c){
        int x = a - 'A';
        int y = b - 'A';
        g[x][y] = c;
    }
    public static void main(String[] args) {
        // 初始化边
        for (int i = 0; i < n; i++) {
            Arrays.fill(g[i],0x3f3f3f3f);
        }
        Arrays.fill(dist, 0x3f3f3f); 
        dist[0] = 0;
        add('A','B',2);
        add('A','C',1);
        add('A','D',1);
        add('A','D',1);
        add('B','J',2);
        add('B','G',1);
        add('C','D',3);
        add('C','F',3);
        add('C','G',3);
        add('D','E',1);
        add('D','G',2);
        add('D','H',1);
        add('D','I',2);
        add('E','H',1);
        add('E','I',3);
        add('F','G',1);
        add('F','J',1);
        add('G','F',1);
        add('G','I',3);
        add('G','K',2);
        add('H','I',1);
        add('H','L',2);
        add('I','M',3);
        add('J','S',2);
        add('K','N',1);
        add('K','L',3);
        add('K','P',2);
        add('L','M',1);
        add('L','R',1);
        add('M','N',2);
        add('M','Q',1);
        add('M','S',1);
        add('N','P',1);
        add('O','P',1);
        add('O','Q',1);
        add('O','R',3);
        add('R','S',1);
        System.out.println(dijkstar());
    }

    /**
     * dijkstar算法基于贪心算法,选取每一步的最优解
     * @return
     */
    public static int dijkstar(){

        for (int i = 0; i < n - 1; i++) {
            int t = -1;
            /** 找到没有放到已确定节点里的最小节点 */
            for (int j = 0; j < n; j++) {
                if(!s[j] && (t == -1 || dist[t] > dist[j])){
                    t = j;
                }
            }
            /**用这个节点来更新其他的节点的距离 */
            for (int j = 0; j < n; j++) {
                if (dist[j] > dist[t] + g[t][j]) {
                    dist[j] = dist[t] + g[t][j];
                }
            }
            s[t] = true;
        }
        if (dist[13] != 0x3f3f3f3f) {
            return dist[13];
        }
        return -1;
    }
}

四、总结:

题目和思想都不是特别难,主要是要真正的理解问题,然后适当的去记忆模板的整体实现。