forked from TheAlgorithms/Go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dijkstra.go
62 lines (53 loc) · 1018 Bytes
/
dijkstra.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package graph
import "github.com/TheAlgorithms/Go/sort"
type Item struct {
node int
dist int
}
func (a Item) More(b any) bool {
// reverse direction for minheap
return a.dist < b.(Item).dist
}
func (a Item) Idx() int {
return a.node
}
func (g *Graph) Dijkstra(start, end int) (int, bool) {
visited := make(map[int]bool)
nodes := make(map[int]*Item)
nodes[start] = &Item{
dist: 0,
node: start,
}
pq := sort.MaxHeap{}
pq.Init(nil)
pq.Push(*nodes[start])
visit := func(curr Item) {
visited[curr.node] = true
for n, d := range g.edges[curr.node] {
if visited[n] {
continue
}
item := nodes[n]
dist2 := curr.dist + d
if item == nil {
nodes[n] = &Item{node: n, dist: dist2}
pq.Push(*nodes[n])
} else if item.dist > dist2 {
item.dist = dist2
pq.Update(*item)
}
}
}
for pq.Size() > 0 {
curr := pq.Pop().(Item)
if curr.node == end {
break
}
visit(curr)
}
item := nodes[end]
if item == nil {
return -1, false
}
return item.dist, true
}