2026-03-12
By the end of this lab session, you should be able to:
Understand single-source shortest path algorithms: Explain how Dijkstra’s (priority queue, greedy) and Bellman-Ford (relaxation iterations) work, compare their time complexities, and identify when to use each based on graph properties (negative weights, cycles).
Implement Dijkstra’s algorithm: Implement Dijkstra’s in C++ using priority queues and maps, handle string-based vertex names with adjacency lists, track predecessors, and detect negative edge weights.
Apply shortest path algorithms: Use Bellman-Ford to solve pathfinding problems in game development and model grid-based problems as graphs to find optimal paths.
This lab consists of three main activities:
This activity consists of multiple choice questions to test your understanding of single-source shortest path algorithms, specifically Dijkstra’s algorithm and Bellman-Ford algorithm.
Submission (xSITe Quizzes, 10 marks). Complete the quiz “Week 10 Lab Exercise 1” on xSITe.
Before attempting the quiz, make sure you understand:
You are given a weighted directed graph represented as an adjacency list, where each vertex is identified by a string name. Your task is to implement Dijkstra’s algorithm to find the shortest distances from a given source vertex to all other vertices in the graph.
This is a classic single-source shortest path problem where:
Consider the following graph:
A --3--> B
| |
1 2
| |
v v
C --4--> D
A courier hub in Woodlands (A) needs to deliver a parcel to a customer in Bukit Panjang (D). The values on the map represent the actual distance in kilometers (km) between the locations.
Using the starting point of Woodlands (A), calculate the shortest distance to each town:
Distance to Woodlands (A): 0 km (Origin)
Shortest distance to Yishun (B): 3 km (Direct via Woodlands (A) → Yishun (B) )
Shortest distance to Kranji (C): 1 km (Direct via Woodlands (A) → Kranji (C) )
Shortest distance to Bukit Panjang (D): 5 km (path A → C → D with cost 1 + 4 = 5, or A → B → D with cost 3 + 2 = 5)
Result: In this specific graph, both the Yishun route and the Kranji route result in a total distance of 5 km.
Download dijkstra.zip from xSITe. The file dijkstra.cpp contains a stub for function:
Input format: The graph is represented as an adjacency list:
graph: A map where keys are vertex names (strings) and values are vectors of Edge structuresEdge has:
to: destination vertex name (string)weight: edge weight (non-negative integer)start: the source vertex namepredecessors: output parameter to store the predecessor of each vertex (for path reconstruction)Output format: Return a map where keys are vertex names and values are the shortest distances from start. If a vertex is unreachable, its distance should be INT_MAX.
INT_MAX except the source (distance = 0)predecessors map when relaxing edgesSubmission (Gradescope, 20 marks). Submit your completed dijkstra.cpp to the “Week 10 Lab Exercise 2” assignment on Gradescope.
Initialization: All distances = INT_MAX, source = 0, all vertices unvisited, predecessors = empty strings.
Priority Queue: Use std::priority_queue with std::greater for min-heap. Stores (distance, vertex_name) pairs, always processes minimum distance first.
Relaxation: For each edge, check negative weights (return empty map if found). If dist[current] + weight < dist[neighbor], update distance and predecessor, push to queue.
Lazy Deletion: Multiple entries per vertex may exist in queue; skip already visited vertices to avoid update/remove operations.
Edge Cases: Negative weights return empty map; unreachable vertices remain INT_MAX; disconnected graphs handled naturally.
You are designing a pathfinding system for a 2D grid-based game. The game world consists of a grid where each cell has a terrain cost (movement cost). The player character starts at position \((s_r, s_c)\) and needs to reach the target position \((t_r, t_c)\).
The character can move in 4 directions (up, down, left, right) to adjacent cells. The cost of moving from one cell to an adjacent cell is the terrain cost of the destination cell. Your task is to find the minimum total cost to move from the start to the target.
This is a classic single-source shortest path problem where:
Consider a \(3 \times 4\) game grid with terrain costs:
0 1 2 3
-------------
0| 1 5 2 1
1| 3 1 4 2
2| 1 2 1 3
Starting at \((0, 0)\) with cost 1, and target at \((2, 3)\) with cost 3.
Example path: \((0,0) \rightarrow (0,1) \rightarrow (1,1) \rightarrow (2,1) \rightarrow (2,2) \rightarrow (2,3)\)
Path cost: \(1 + 5 + 1 + 2 + 1 + 3 = 13\) (includes start cell cost)
Note: The optimal path might be different! Use Bellman-Ford to find it.
Download: Get game_pathfinding.zip from xSITe. The starter file game_pathfinding.cpp contains the stub:
Input format:
rows colsstart_r start_c target_r target_crows lines: each line has cols integers representing terrain costsOutput format: Return the minimum total cost to move from start to target (including the cost of the start cell).
idx = row * cols + colSubmission (Gradescope, 30 marks). Upload completed game_pathfinding.cpp to Gradescope “Week 10 Lab Exercise 3”.
Bellman-Ford: Relax all edges \((|V| - 1)\) times. Slower but handles negative weights and detects cycles.
Graph: Vertices = grid cells \((row, col)\); edges = 4-neighbour connections; edge weight = terrain cost of destination cell.
By the end of this lab you should be able to:
This lab covered both Minimum Spanning Trees and Single-Source Shortest Paths as fundamental graph algorithms. The remaining weeks cover:
Versatile optimization techniques for solving complex problems
Week 10: Single-Source Shortest Paths (Lab)