Challenge - 5 Problems
Prim's Algorithm Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediateOutput of Prim's Algorithm on a Simple Graph
What is the printed state of the minimum spanning tree edges after running Prim's algorithm on this graph?
DSA Go
package main import ( "container/heap" "fmt" ) type Edge struct { to, weight int } type Item struct { node, weight int } type PriorityQueue []Item func (pq PriorityQueue) Len() int { return len(pq) } func (pq PriorityQueue) Less(i, j int) bool { return pq[i].weight < pq[j].weight } func (pq PriorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] } func (pq *PriorityQueue) Push(x interface{}) { *pq = append(*pq, x.(Item)) } func (pq *PriorityQueue) Pop() interface{} { old := *pq n := len(old) item := old[n-1] *pq = old[0 : n-1] return item } func prim(graph [][]Edge) []string { n := len(graph) visited := make([]bool, n) pq := &PriorityQueue{} heap.Init(pq) heap.Push(pq, Item{node: 0, weight: 0}) visited[0] = true result := []string{} for pq.Len() > 0 { item := heap.Pop(pq).(Item) current := item.node weight := item.weight if weight != 0 { result = append(result, fmt.Sprintf("Edge to node %d with weight %d", current, weight)) } visited[current] = true for _, edge := range graph[current] { if !visited[edge.to] { heap.Push(pq, Item{node: edge.to, weight: edge.weight}) } } } return result } func main() { graph := [][]Edge{ {{to: 1, weight: 2}, {to: 3, weight: 6}}, {{to: 0, weight: 2}, {to: 2, weight: 3}, {to: 3, weight: 8}, {to: 4, weight: 5}}, {{to: 1, weight: 3}, {to: 4, weight: 7}}, {{to: 0, weight: 6}, {to: 1, weight: 8}, {to: 4, weight: 9}}, {{to: 1, weight: 5}, {to: 2, weight: 7}, {to: 3, weight: 9}}, } mst := prim(graph) for _, edge := range mst { fmt.Println(edge) } }
Attempts:
2 left
💡 Hint
Trace the algorithm starting from node 0 and always pick the smallest edge connecting to an unvisited node.
✗ Incorrect
Prim's algorithm starts at node 0, picks the smallest edge to node 1 (weight 2), then from nodes 0 and 1 picks edge to node 2 (weight 3), then edge to node 4 (weight 5), and finally edge to node 3 (weight 6).
🧠 Conceptual
intermediateUnderstanding Prim's Algorithm Behavior
Which statement correctly describes Prim's algorithm behavior on a connected weighted graph?
Attempts:
2 left
💡 Hint
Think about how the tree grows step by step.
✗ Incorrect
Prim's algorithm starts from any node and grows the MST by always adding the smallest edge that connects a new node to the existing tree.
🔧 Debug
advancedIdentify the Bug in Prim's Algorithm Implementation
What error will this code produce when running Prim's algorithm on a graph?
DSA Go
package main import ( "container/heap" "fmt" ) type Edge struct { to, weight int } type Item struct { node, weight int } type PriorityQueue []Item func (pq PriorityQueue) Len() int { return len(pq) } func (pq PriorityQueue) Less(i, j int) bool { return pq[i].weight < pq[j].weight } func (pq PriorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] } func (pq *PriorityQueue) Push(x interface{}) { *pq = append(*pq, x.(Item)) } func (pq *PriorityQueue) Pop() interface{} { old := *pq n := len(old) item := old[n-1] *pq = old[0 : n-1] return item } func prim(graph [][]Edge) []string { n := len(graph) visited := make([]bool, n) pq := &PriorityQueue{} heap.Init(pq) heap.Push(pq, Item{node: 0, weight: 0}) result := []string{} for pq.Len() > 0 { item := heap.Pop(pq).(Item) current := item.node weight := item.weight if visited[current] { continue } visited[current] = true if weight != 0 { result = append(result, fmt.Sprintf("Edge to node %d with weight %d", current, weight)) } for _, edge := range graph[current] { if !visited[edge.to] { heap.Push(pq, Item{node: edge.to, weight: edge.weight}) } } } return result } func main() { graph := [][]Edge{ {{to: 1, weight: 2}, {to: 3, weight: 6}}, {{to: 0, weight: 2}, {to: 2, weight: 3}, {to: 3, weight: 8}, {to: 4, weight: 5}}, {{to: 1, weight: 3}, {to: 4, weight: 7}}, {{to: 0, weight: 6}, {to: 1, weight: 8}, {to: 4, weight: 9}}, {{to: 1, weight: 5}, {to: 2, weight: 7}, {to: 3, weight: 9}}, } mst := prim(graph) for _, edge := range mst { fmt.Println(edge) } }
Attempts:
2 left
💡 Hint
Check when nodes are marked visited and when edges are pushed to the queue.
✗ Incorrect
The code pushes edges to the priority queue without checking if the node is already visited, which can cause duplicate edges to be processed and included in the MST.
❓ Predict Output
advancedOutput of Prim's Algorithm on a Disconnected Graph
What is the output of running Prim's algorithm on this disconnected graph starting from node 0?
DSA Go
package main import ( "container/heap" "fmt" ) type Edge struct { to, weight int } type Item struct { node, weight int } type PriorityQueue []Item func (pq PriorityQueue) Len() int { return len(pq) } func (pq PriorityQueue) Less(i, j int) bool { return pq[i].weight < pq[j].weight } func (pq PriorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] } func (pq *PriorityQueue) Push(x interface{}) { *pq = append(*pq, x.(Item)) } func (pq *PriorityQueue) Pop() interface{} { old := *pq n := len(old) item := old[n-1] *pq = old[0 : n-1] return item } func prim(graph [][]Edge) []string { n := len(graph) visited := make([]bool, n) pq := &PriorityQueue{} heap.Init(pq) heap.Push(pq, Item{node: 0, weight: 0}) result := []string{} for pq.Len() > 0 { item := heap.Pop(pq).(Item) current := item.node weight := item.weight if visited[current] { continue } visited[current] = true if weight != 0 { result = append(result, fmt.Sprintf("Edge to node %d with weight %d", current, weight)) } for _, edge := range graph[current] { if !visited[edge.to] { heap.Push(pq, Item{node: edge.to, weight: edge.weight}) } } } return result } func main() { graph := [][]Edge{ {{to: 1, weight: 4}}, {{to: 0, weight: 4}}, {{to: 3, weight: 1}}, {{to: 2, weight: 1}}, } mst := prim(graph) for _, edge := range mst { fmt.Println(edge) } }
Attempts:
2 left
💡 Hint
Prim's algorithm only visits nodes reachable from the start node.
✗ Incorrect
The graph has two disconnected parts: nodes 0 and 1 connected, and nodes 2 and 3 connected. Starting from node 0, only node 1 is reachable, so only one edge is included.
🚀 Application
expertMinimum Spanning Tree Weight Calculation
Given the following weighted graph, what is the total weight of the minimum spanning tree found by Prim's algorithm starting at node 0?
DSA Go
package main import ( "container/heap" ) type Edge struct { to, weight int } type Item struct { node, weight int } type PriorityQueue []Item func (pq PriorityQueue) Len() int { return len(pq) } func (pq PriorityQueue) Less(i, j int) bool { return pq[i].weight < pq[j].weight } func (pq PriorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] } func (pq *PriorityQueue) Push(x interface{}) { *pq = append(*pq, x.(Item)) } func (pq *PriorityQueue) Pop() interface{} { old := *pq n := len(old) item := old[n-1] *pq = old[0 : n-1] return item } func primTotalWeight(graph [][]Edge) int { n := len(graph) visited := make([]bool, n) pq := &PriorityQueue{} heap.Init(pq) heap.Push(pq, Item{node: 0, weight: 0}) totalWeight := 0 for pq.Len() > 0 { item := heap.Pop(pq).(Item) current := item.node weight := item.weight if visited[current] { continue } visited[current] = true totalWeight += weight for _, edge := range graph[current] { if !visited[edge.to] { heap.Push(pq, Item{node: edge.to, weight: edge.weight}) } } } return totalWeight } func main() { graph := [][]Edge{ {{to: 1, weight: 10}, {to: 2, weight: 6}, {to: 3, weight: 5}}, {{to: 0, weight: 10}, {to: 3, weight: 15}}, {{to: 0, weight: 6}, {to: 3, weight: 4}}, {{to: 0, weight: 5}, {to: 1, weight: 15}, {to: 2, weight: 4}}, } weight := primTotalWeight(graph) println(weight) }
Attempts:
2 left
💡 Hint
Add the weights of edges chosen by Prim's algorithm starting at node 0.
✗ Incorrect
The MST edges are: 0-3 (5), 3-2 (4), and 0-1 (10). Total weight = 5 + 4 + 10 = 19.
