Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述:
如下图所示,G是一个无向图,其中蓝色边的长度是 1、橘色边的长度是 2、绿色边的长度是 3。
则从 A到 S 的最短距离是多少?
运行限制
- 最大运行时间: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;
}
}
四、总结:
题目和思想都不是特别难,主要是要真正的理解问题,然后适当的去记忆模板的整体实现。