Network Delay Time
LeetCode 743 · View on LeetCode
Dijkstra's algorithm — find the time it takes for a signal to reach all nodes. Return the maximum distance (slowest node), or -1 if any node is unreachable. Nodes are 1-indexed.
package main
import (
"container/heap"
"fmt"
"math"
)
type Edge struct {
To, Weight int
}
type Item struct {
Dist, Node int // Dist: total distance from source, Node: target node
}
type MinHeap []Item
func (h MinHeap) Len() int { return len(h) }
func (h MinHeap) Less(i, j int) bool { return h[i].Dist < h[j].Dist }
func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *MinHeap) Push(x any) { *h = append(*h, x.(Item)) }
func (h *MinHeap) Pop() any {
old := *h
x := old[len(old)-1]
*h = old[:len(old)-1]
return x
}
func networkDelayTime(times [][]int, n int, k int) int {
adj := map[int][]Edge{}
for _, t := range times {
adj[t[0]] = append(adj[t[0]], Edge{t[1], t[2]})
}
dist := make([]int, n+1) // 1-indexed
for i := range dist {
dist[i] = math.MaxInt
}
dist[k] = 0
pq := &MinHeap{{0, k}}
heap.Init(pq)
for pq.Len() > 0 {
curr := heap.Pop(pq).(Item)
if curr.Dist > dist[curr.Node] {
continue
}
for _, edge := range adj[curr.Node] {
newDist := dist[curr.Node] + edge.Weight
if newDist < dist[edge.To] {
dist[edge.To] = newDist
heap.Push(pq, Item{newDist, edge.To})
}
}
}
maxDist := 0
for i := 1; i <= n; i++ { // skip index 0
if dist[i] == math.MaxInt {
return -1 // unreachable node
}
if dist[i] > maxDist {
maxDist = dist[i]
}
}
return maxDist
}
func main() {
times := [][]int{{2, 1, 1}, {2, 3, 1}, {3, 4, 1}}
fmt.Println(networkDelayTime(times, 4, 2)) // 2
}