|
| 1 | +package graph |
| 2 | + |
| 3 | +import ( |
| 4 | + "container/heap" |
| 5 | +) |
| 6 | + |
| 7 | +// Edge represents a directed edge with a weight. |
| 8 | +type Edge struct { |
| 9 | + node, weight int |
| 10 | +} |
| 11 | + |
| 12 | +// MinHeap is a priority queue to store nodes and their cumulative distances from the start. |
| 13 | +type MinHeap [][]int |
| 14 | + |
| 15 | +// Implement heap.Interface for MinHeap |
| 16 | + |
| 17 | +func (h MinHeap) Len() int { |
| 18 | + return len(h) |
| 19 | +} |
| 20 | + |
| 21 | +func (h MinHeap) Less(i, j int) bool { |
| 22 | + return h[i][0] < h[j][0] |
| 23 | +} |
| 24 | + |
| 25 | +func (h MinHeap) Swap(i, j int) { |
| 26 | + h[i], h[j] = h[j], h[i] |
| 27 | +} |
| 28 | + |
| 29 | +func (h *MinHeap) Push(x interface{}) { |
| 30 | + *h = append(*h, x.([]int)) |
| 31 | +} |
| 32 | + |
| 33 | +func (h *MinHeap) Pop() interface{} { |
| 34 | + old := *h |
| 35 | + n := len(old) |
| 36 | + x := old[n-1] |
| 37 | + *h = old[0 : n-1] |
| 38 | + return x |
| 39 | +} |
| 40 | + |
| 41 | +// networkDelayTime calculates the time it will take for all nodes to receive a signal sent from a given node. |
| 42 | +func NetworkDelayTime(times [][]int, n int, k int) int { |
| 43 | + // Create the graph using an adjacency list representation. |
| 44 | + graph := make(map[int][]Edge) |
| 45 | + for _, time := range times { |
| 46 | + u, v, w := time[0], time[1], time[2] |
| 47 | + graph[u] = append(graph[u], Edge{v, w}) |
| 48 | + } |
| 49 | + |
| 50 | + // Min-heap to get the node with the shortest cumulative distance first. |
| 51 | + minHeap := &MinHeap{} |
| 52 | + heap.Init(minHeap) |
| 53 | + heap.Push(minHeap, []int{0, k}) // Start with the source node `k` with a distance of 0. |
| 54 | + |
| 55 | + // Visited set to store nodes that have been processed. |
| 56 | + visited := make(map[int]bool) |
| 57 | + maxDelay := 0 |
| 58 | + |
| 59 | + // Process nodes in the heap. |
| 60 | + for minHeap.Len() > 0 { |
| 61 | + current := heap.Pop(minHeap).([]int) |
| 62 | + currentDistance := current[0] |
| 63 | + currentNode := current[1] |
| 64 | + |
| 65 | + // Skip processing if the node has already been visited. |
| 66 | + if visited[currentNode] { |
| 67 | + continue |
| 68 | + } |
| 69 | + visited[currentNode] = true |
| 70 | + maxDelay = currentDistance |
| 71 | + |
| 72 | + // Iterate over all neighbors of the current node. |
| 73 | + for _, edge := range graph[currentNode] { |
| 74 | + if !visited[edge.node] { |
| 75 | + heap.Push(minHeap, []int{currentDistance + edge.weight, edge.node}) |
| 76 | + } |
| 77 | + } |
| 78 | + } |
| 79 | + |
| 80 | + // If all nodes are visited, return the maximum delay time; otherwise, return -1. |
| 81 | + if len(visited) == n { |
| 82 | + return maxDelay |
| 83 | + } |
| 84 | + return -1 |
| 85 | +} |
0 commit comments