From f802fc7e999210c70bba081ba79f3be21b4b3a81 Mon Sep 17 00:00:00 2001 From: HuangLM03 <2306725926@qq.com> Date: Mon, 17 Feb 2025 02:13:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0kamacoder/0047.=E5=8F=82?= =?UTF-8?q?=E4=BC=9Adijkstra=E6=9C=B4=E7=B4=A0=E7=9A=84Go=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...74\232dijkstra\346\234\264\347\264\240.md" | 120 +++++++++++++++++- 1 file changed, 114 insertions(+), 6 deletions(-) diff --git "a/problems/kamacoder/0047.\345\217\202\344\274\232dijkstra\346\234\264\347\264\240.md" "b/problems/kamacoder/0047.\345\217\202\344\274\232dijkstra\346\234\264\347\264\240.md" index e71e9d5374..5fd57965ad 100644 --- "a/problems/kamacoder/0047.\345\217\202\344\274\232dijkstra\346\234\264\347\264\240.md" +++ "b/problems/kamacoder/0047.\345\217\202\344\274\232dijkstra\346\234\264\347\264\240.md" @@ -114,7 +114,7 @@ dijkstra 算法 同样是贪心的思路,不断寻找距离 源点最近的没 ### 模拟过程 ------------ +----------- 0、初始化 @@ -130,7 +130,7 @@ minDist数组数值初始化为int最大值。 此时所有节点都没有被访问过,所以 visited数组都为0 ---------------- +--------------- 以下为dijkstra 三部曲 @@ -555,13 +555,13 @@ int main() { 那我们来看dijkstra 求解的路径是什么样的,继续dijkstra 三部曲来模拟 :(dijkstra模拟过程上面已经详细讲过,以下只模拟重要过程,例如如何初始化就省略讲解了) ------------ +----------- 初始化: ![](https://code-thinking-1253855093.file.myqcloud.com/pics/20240227104801.png) ---------------- +--------------- 1、选源点到哪个节点近且该节点未被访问过 @@ -632,7 +632,7 @@ int main() { 节点5的加入,而节点5 没有链接其他节点, 所以不用更新minDist数组,仅标记节点5被访问过了 ------------- +------------ 1、选源点到哪个节点近且该节点未被访问过 @@ -646,7 +646,7 @@ int main() { ![](https://code-thinking-1253855093.file.myqcloud.com/pics/20240227110711.png) --------------- +-------------- 至此dijkstra的模拟过程就结束了,根据最后的minDist数组,我们求 节点1 到 节点5 的最短路径的权值总和为 3,路径: 节点1 -> 节点3 -> 节点4 -> 节点5 @@ -865,6 +865,114 @@ if __name__ == "__main__": ### Go +```go +package main + +import( + "fmt" + "os" + "bufio" + "strconv" + "strings" + "math" +) + +func main() { + // 创建Reader从标准输入中读取数据 + reader := bufio.NewReader(os.Stdin) + + // 以字符串的形式读取一行 + line, _ := reader.ReadString('\n') + // 去掉字符串前后可能存在的空格 + line = strings.TrimSpace(line) + // 以空格作为分隔符分割字符串,得到数字的字符串形式 + params := strings.Split(line, " ") + // 字符串转化为数字,得到n和m,其中n为汽车站数,m为公路数 + n, _ := strconv.Atoi(params[0]) + m, _ := strconv.Atoi(params[1]) + + // 存储从源点到每个节点的最短距离 + minDist := initSliceInt(math.MaxInt32, n + 1) + minDist[1] = 0 + // 记录顶点是否被访问过 + visited := initSliceBool(false, n + 1) + + // 存储每个车站之间的距离 + grid := make([][]int, n + 1) + for i := 1; i <= n; i++ { + grid[i] = initSliceInt(math.MaxInt32, n + 1) + grid[i][i] = 0 + } + for i := 1; i <= m; i++ { + line, _ = reader.ReadString('\n') + line = strings.TrimSpace(line) + params = strings.Split(line, " ") + a, _ := strconv.Atoi(params[0]) + b, _ := strconv.Atoi(params[1]) + c, _ := strconv.Atoi(params[2]) + + grid[a][b] = c + } + + // Dijkstra算法 + for i := 1; i <= n; i++ { + cur := -1 + // 1、选距离源点最近且未访问过的节点 + for j := 1; j <= n; j++ { + if visited[j] == false && (cur == -1 || minDist[cur] > minDist[j]) { + cur = j; + } + } + + // 2、标记该节点已被访问 + visited[cur] = true + + /* + 3、更新非访问节点到源点的距离(即更新minDist数组)。实际更新时无需判断 + 节点是否被访问过,因为1.的限制,即使更新被访问过的点也没有任何影响。 + */ + for j := 1; j <= n; j++ { + minDist[j] = min(minDist[j], minDist[cur] + grid[cur][j]) + } + + } + + if minDist[n] == math.MaxInt32 { + // 不能到达终点 + fmt.Print(-1) + } else { + // 到达终点最短路径 + fmt.Print(minDist[n]) + } +} + +// 创建int类型的切片 +func initSliceInt(value int, count int) []int { + result := make([]int, count) + for i := range result { + result[i] = value + } + return result +} + +// 创建bool类型的切片 +func initSliceBool(value bool, count int) []bool { + result := make([]bool, count) + for i := range result { + result[i] = value + } + return result +} + +// 比较两个int类型的大小,返回较小的一个 +func min(a, b int) int { + if a > b { + return b + } + return a +} +``` + ### Rust ### JavaScript