Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Shortest Path with Alternating Colors in Python
Suppose we have a directed graph with nodes labelled 0, 1, ..., n-1. In this graph, each edge is colored with either red or blue colors, and there could be self-edges or parallel edges. Each [i, j] in red_edges indicates a red directed edge from node i to node j. Similarly, each [i, j] in blue_edges indicates a blue directed edge from node i to node j. We need to find an array answer of length n, where each answer[X] is the length of the shortest path from node 0 to node X such that the edge colors alternate along the path (or -1 if such a path doesn't exist).
Example
If the input is n = 3, red_edges = [[0,1],[1,2]] and blue_edges = [], then the output will be [0, 1, -1].
Algorithm
To solve this problem, we use BFS (Breadth-First Search) with state tracking. The key insight is that we need to track both the current node and the color of the last edge used to reach it.
The algorithm follows these steps ?
Create adjacency lists for red and blue edges separately
Use BFS starting from node 0 with both possible starting colors
Track visited states as (node, last_color) pairs to avoid cycles
For each step, alternate the edge color and update the shortest distance
Return -1 for unreachable nodes
Implementation
from collections import deque
class Solution:
def shortestAlternatingPaths(self, n, red_edges, blue_edges):
# Initialize result array with infinity
result = [float("inf")] * n
# Create adjacency lists for red and blue edges
red_graph = [[] for _ in range(n)]
blue_graph = [[] for _ in range(n)]
# Build adjacency lists
for start, end in red_edges:
red_graph[start].append(end)
for start, end in blue_edges:
blue_graph[start].append(end)
# BFS with alternating colors
self.bfs(red_graph, blue_graph, n, result, start_with_red=True)
self.bfs(red_graph, blue_graph, n, result, start_with_red=False)
# Convert infinity to -1 for unreachable nodes
for i in range(len(result)):
if result[i] == float('inf'):
result[i] = -1
return result
def bfs(self, red_graph, blue_graph, n, result, start_with_red):
visited = set()
queue = deque([(0, start_with_red, 0)]) # (node, use_red_next, steps)
while queue:
current_node, use_red, steps = queue.popleft()
# Update minimum distance to current node
result[current_node] = min(result[current_node], steps)
# Choose the graph based on current color
if use_red:
graph = red_graph
else:
graph = blue_graph
# Explore neighbors with alternating color
for neighbor in graph[current_node]:
state = (neighbor, not use_red) # Alternate color for next step
if state not in visited:
visited.add(state)
queue.append((neighbor, not use_red, steps + 1))
# Test the solution
solution = Solution()
print(solution.shortestAlternatingPaths(3, [[0,1], [1,2]], []))
[0, 1, -1]
How It Works
The algorithm works by:
State Representation: Each state is (node, last_color_used) to track alternating requirement
Double BFS: We run BFS twice - once starting with red edges, once with blue edges
Color Alternation: At each step, we switch to the opposite color graph
Shortest Path: BFS guarantees we find the shortest alternating path
Example Walkthrough
For n=3, red_edges=[[0,1],[1,2]], blue_edges=[]:
Node 0: Distance 0 (starting point)
Node 1: Distance 1 (via red edge 0?1)
Node 2: Distance -1 (cannot reach with alternating colors, as we need blue edge after red but none exists)
Conclusion
This solution uses BFS with state tracking to find shortest alternating paths. The key insight is treating (node, color) as distinct states and running BFS from both possible starting colors to ensure we find the optimal solution.
