Program to find minimum number of buses required to reach final target in python

Suppose we have a n x 3 matrix where each row contains three fields [src, dest, id] − this means the bus has route from src to dest. It takes one unit of money to get on a new bus, but if we stay on the same bus we have to pay one unit only. We have to find the minimum cost necessary to take the bus from location 0 to the final stop (largest location). If there is no solution return -1.

Problem Example

Consider the following bus routes ?

Source Destination Bus ID
0 1 0
1 2 0
2 3 0
3 5 1
5 0 2

The output will be 2, as we can take bus 0 at location 0 and get out at location 3. Then we take bus 1 to reach location 5.

Algorithm Steps

To solve this problem, we will use Dijkstra's algorithm with a priority queue ?

  • start := 0
  • target := maximum location in the given matrix
  • adj := adjacency list to store connections
  • Use a min-heap to explore paths with minimum cost first
  • Track visited states to avoid cycles
  • Return the minimum cost when target is reached

Implementation

from collections import defaultdict
from heapq import heappop, heappush

class Solution:
    def solve(self, connections):
        start = 0
        target = max(max(y, x) for y, x, _ in connections)
        
        # Build adjacency list
        adj = defaultdict(list)
        for src, dest, bus_id in connections:
            adj[src].append((dest, bus_id))
        
        # Priority queue: (cost, current_position, current_bus_id)
        heap = [(0, start, -1)]
        seen = defaultdict(set)
        
        while heap:
            cost, cur_pos, cur_bus = heappop(heap)
            
            # Reached target
            if cur_pos == target:
                return cost
            
            # Skip if already visited this position with same bus
            if cur_bus in seen[cur_pos]:
                continue
            seen[cur_pos].add(cur_bus)
            
            # Explore all possible next positions
            for next_pos, next_bus in adj[cur_pos]:
                next_cost = cost
                # If changing bus, add 1 to cost
                if next_bus != cur_bus:
                    next_cost += 1
                heappush(heap, (next_cost, next_pos, next_bus))
        
        return -1

# Test the solution
ob = Solution()
matrix = [
    [0, 1, 0],
    [1, 2, 0],
    [2, 3, 0],
    [3, 5, 1],
    [5, 0, 2]
]
print(ob.solve(matrix))
2

How It Works

The algorithm uses a modified Dijkstra's approach where ?

  • State: (cost, position, bus_id) represents current situation
  • Cost increment: Only when switching to a different bus
  • Priority queue: Always explores the lowest cost path first
  • Visited tracking: Prevents revisiting same position with same bus

Key Points

  • Time complexity: O(E log V) where E is edges and V is vertices
  • Space complexity: O(V + E) for adjacency list and visited states
  • Returns -1 if no path exists to the target location
  • Handles cycles by tracking visited (position, bus) pairs

Conclusion

This solution efficiently finds the minimum number of bus changes needed to reach the target using Dijkstra's algorithm. The key insight is treating bus changes as cost increments while maintaining optimal pathfinding.

Updated on: 2026-03-25T13:08:43+05:30

435 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements