胡扯:这个问题,来自leetcode上面的一个题。两天前已经解答出来了,但是由于乱七八糟的事情,还没有来得及做一个总结。好吧,一个算法竟然前后这么几天才完结。真的是。。。
你可以先去 百度百科 看看一下这个算法的定义。
下面将一步步诱导你写出这个算法。
1、大佬级别人物,直接看下面这个图。就可以写出这个算法的。
2、听一个视频讲解上面gif所表达的意思,再来写出这个算法。(我就是听了讲解之后做出来的)
https://video.tudou.com/v/XMTc5MjQ3NTQwOA==.html?spm=a2hzp.8253869.0.0
3、当你感觉写出来了差不多的时候,你可以去 leetcode 尝试一下这个题
https://leetcode-cn.com/problems/network-delay-time/comments/
4、简单说一下其中要注意的几个点。
4-1:循环的次数,等于 全部节点的个数。
4-2:问题就是每次选取的是那个节点。视频中已经指出了。每次选择 路径(权值)最小的点。(已经选过的点,不再选取)
4-3:再说一下leetcode这个题。你可以理解成,把水倒入一个迷宫,水蔓延到全部点所需的时间。这样你就会发现,这是要我们求出 最长的那个时间了。 我们使用Dijkstra求出,起始点到每个点的距离,然后找到最大的返回就好了。
java代码。 个人感觉代码不是很复杂,比较好理解 (为了方便,这里分开给出方法,和测试代码)
方法:
//寻找最短路径方法 start 是起始点 N 节点个数
static void Dijkstra(int[][] arr,int N,int start){
Map<Integer,Integer> map = new HashMap<>(); //用来存放每次循环后的新状态
Set<Integer> set = new HashSet<>(); //用来存放已经遍历过的节点
int minValue = 1000000000;
// -1 表示走不通
map.put(start,0);
while (N > 0){
set.add(start);
for (int i = 0;i < arr.length; i++){
if ( start == arr[i][0] ){
if ( !map.containsKey( arr[i][1] ) ){ // 还没有遍历过这个点
map.put(arr[i][1],map.get(start)+arr[i][2]);
}
else if ( (map.get(arr[i][1]) == -1 ) || ( map.get(start)+arr[i][2] < map.get(arr[i][1]) ) ){ //如果遍历过,就看看那种走法更好
map.put(arr[i][1],map.get(start)+arr[i][2]);
}
} else if( !map.containsKey( arr[i][1] ) ){ //判断这个点是否已经遍历过了
//没有遍历 给它一个 -1
map.put( arr[i][1],-1 );
}
}
// 找到路径最短的那个节点 下次从他开始遍历 并且这个节点不能是已经遍历过的
for (Integer i : map.keySet()){
if ( set.contains(i) )
continue;
// -1 表示无穷大
if (map.get(i) < minValue && map.get(i) != -1){
minValue = map.get(i);
start = i;
}
}
minValue = 1000000000;
N--;
}
// 打印
for (Integer i : map.keySet()){
System.out.println( i + " : " + map.get(i) );
}
}
测试代码:
public static void main(String[] args) {
// int[][] arr = { {1,2,1},{2,3,2},{1,3,2} };
// Dijkstra(arr,3,1);
// int[][] arr = { {1,2,7},{1,3,9},{1,6,14},{2,4,15},{3,4,11},{3,6,2},{4,5,6},{6,5,9} };
// Dijkstra(arr,6,1);
// int[][] arr = { {4,2,76},{1,3,79},{3,1,81},{4,3,30},{2,1,47},
// {1,5,61},{1,4,99},{3,4,68},{3,5,46},{4,1,6},{5,4,7},
// {5,3,44},{4,5,19},{2,3,13},{3,2,18},{1,2,0},{5,1,25},{2,5,58},{2,4,77},{5,2,74} };
// Dijkstra(arr,5,3);
// int[][] arr = { {1,2,1},{2,3,7},{1,3,4},{2,1,2} };
// Dijkstra(arr,4,1);
int[][] arr = { {1,2,1} };
Dijkstra(arr,2,2);
}