Implement **Dijkstra's algorithm** to find the shortest path in a weighted graph. ```py import heapq def dijkstra(graph, start): # Initialize distances to all nodes as infinity distances = {node: float('inf') for node in graph} # Distance from start node to itself is 0 distances[start] = 0 # Priority queue to keep track of nodes to visit priority_queue = [(0, start)] while priority_queue: # Pop the node with the smallest distance from the priority queue current_distance, current_node = heapq.heappop(priority_queue) # If we already found a shorter path to this node, continue if current_distance > distances[current_node]: continue # Explore neighbors of the current node for neighbor, weight in graph[current_node].items(): distance = current_distance + weight # If we found a shorter path to the neighbor, update its distance if distance < distances[neighbor]: distances[neighbor] = distance # Add the neighbor to the priority queue heapq.heappush(priority_queue, (distance, neighbor)) return distances # Example usage: graph = { 'A': {'B': 3, 'C': 1}, 'B': {'A': 3, 'C': 7, 'D': 5}, 'C': {'A': 1, 'B': 7, 'D': 2}, 'D': {'B': 5, 'C': 2} } start_node = 'A' shortest_distances = dijkstra(graph, start_node) print("Shortest distances from node", start_node, ":") print(shortest_distances) ``` As a challenge I leave you with this exercise. Leave your answer in the comments: **Segment Tree**: Implement a segment tree to solve range queries on an array.