Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加kamacoder/0047.参会dijkstra朴素的Go版本 #2898

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 114 additions & 6 deletions problems/kamacoder/0047.参会dijkstra朴素.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ dijkstra 算法 同样是贪心的思路,不断寻找距离 源点最近的没

### 模拟过程

-----------
-----------

0、初始化

Expand All @@ -130,7 +130,7 @@ minDist数组数值初始化为int最大值。

此时所有节点都没有被访问过,所以 visited数组都为0

---------------
---------------

以下为dijkstra 三部曲

Expand Down Expand Up @@ -555,13 +555,13 @@ int main() {

那我们来看dijkstra 求解的路径是什么样的,继续dijkstra 三部曲来模拟 :(dijkstra模拟过程上面已经详细讲过,以下只模拟重要过程,例如如何初始化就省略讲解了)

-----------
-----------

初始化:

![](https://code-thinking-1253855093.file.myqcloud.com/pics/20240227104801.png)

---------------
---------------

1、选源点到哪个节点近且该节点未被访问过

Expand Down Expand Up @@ -632,7 +632,7 @@ int main() {

节点5的加入,而节点5 没有链接其他节点, 所以不用更新minDist数组,仅标记节点5被访问过了

------------
------------

1、选源点到哪个节点近且该节点未被访问过

Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down