Shortest Path with Alternating Colors in Python

Suppose we have 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 have 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).
So if the input is like n = 3, red_edges = [[0,1],[1,2]] and blue_edges = [], then the output will be [0, 1, -1]
To solve this, we will follow these steps −
Define a method called bfs(), this will take re, be, f and n
Define a method called bfs(), this will take re, be, f and n
define a set called visited, define a queue and insert a triplet [0, f, 0]
define a set called visited, define a queue and insert a triplet [0, f, 0]
while q is not emptyset triplet current, color, step as q[0], and delete from qcolor := complement the value of color (true to false and vice versa)res[current] := min of res[current] and stepif color is non-zero, thenfor each i in re[current]if pair (i, color) is not in visited, then insert (i, color) into visited and insert [i, color, step + 1] into qotherwise when color is 0, thenfor each i in be[current]if pair (i, color) is not in visited, then insert (i, color) into visited and insert [i, color, step + 1] into q
while q is not empty
set triplet current, color, step as q[0], and delete from q
set triplet current, color, step as q[0], and delete from q
color := complement the value of color (true to false and vice versa)
color := complement the value of color (true to false and vice versa)
res[current] := min of res[current] and step
res[current] := min of res[current] and step
if color is non-zero, thenfor each i in re[current]if pair (i, color) is not in visited, then insert (i, color) into visited and insert [i, color, step + 1] into q
if color is non-zero, then
for each i in re[current]if pair (i, color) is not in visited, then insert (i, color) into visited and insert [i, color, step + 1] into q
for each i in re[current]
if pair (i, color) is not in visited, then insert (i, color) into visited and insert [i, color, step + 1] into q
if pair (i, color) is not in visited, then insert (i, color) into visited and insert [i, color, step + 1] into q
otherwise when color is 0, thenfor each i in be[current]if pair (i, color) is not in visited, then insert (i, color) into visited and insert [i, color, step + 1] into q
otherwise when color is 0, then
for each i in be[current]if pair (i, color) is not in visited, then insert (i, color) into visited and insert [i, color, step + 1] into q
for each i in be[current]
if pair (i, color) is not in visited, then insert (i, color) into visited and insert [i, color, step + 1] into q
if pair (i, color) is not in visited, then insert (i, color) into visited and insert [i, color, step + 1] into q
In the main method −
In the main method −
res := an array of infinity values and its size is n
res := an array of infinity values and its size is n
re and be := arrays of n empty arrays
re and be := arrays of n empty arrays
for each element i in r: insert i[1] into re[i[0]]
for each element i in r: insert i[1] into re[i[0]]
for each element i in b: insert i[1] into be[i[0]]
for each element i in b: insert i[1] into be[i[0]]
call bfs(re, be, false, n) and call bfs(re, be, true, n)
call bfs(re, be, false, n) and call bfs(re, be, true, n)
for i in range 0 to length of res – 1if res[i] = inf, then res[i] := -1
for i in range 0 to length of res – 1
if res[i] = inf, then res[i] := -1
if res[i] = inf, then res[i] := -1
return res
return res
Let us see the following implementation to get better understanding −
 Live Demo
class Solution(object):
   def shortestAlternatingPaths(self, n, r, b):
      self.res = [float("inf")] * n
      re = [[] for i in range(n) ]
      be = [[] for i in range(n) ]
      for i in r:
         re[i[0]].append(i[1])
      for i in b:
         be[i[0]].append(i[1])
      self.bfs(re,be,False,n)
      self.bfs(re,be,True,n)
      for i in range(len(self.res)):
         if self.res[i] == float('inf'):
            self.res[i]=-1
      return self.res
   def bfs(self,re,be,f,n):
      visited = set()
      queue = [[0,f,0]]
      while queue:
         current,color,step = queue[0]
         queue.pop(0)
         color = not color
         self.res[current] = min(self.res[current],step)
         if color:
            for i in re[current]:
               if (i,color) not in visited:
                  visited.add((i,color))
                  queue.append([i,color,step+1])
         elif not color:
            for i in be[current]:
               if (i,color) not in visited:
                  visited.add((i,color))
                  queue.append([i,color,step+1])
ob = Solution()
print(ob.shortestAlternatingPaths(3, [[0,1], [1,2]], []))
3
[[0,1],[1,2]]
[]
[0,1,-1]