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 set called visited, define a queue and insert a triplet [0, f, 0]

  • while q is not empty

    • set triplet current, color, step as q[0], and delete from q

    • color := complement the value of color (true to false and vice versa)

    • res[current] := min of res[current] and step

    • 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

    • 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

  • In the main method −

  • res := an array of infinity values and its size is n

  • 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 b: insert i[1] into be[i[0]]

  • call bfs(re, be, false, n) and call bfs(re, be, true, n)

  • for i in range 0 to length of res – 1

    • if res[i] = inf, then res[i] := -1

  • return res

Example(Python)

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]], []))

Input

3
[[0,1],[1,2]]
[]

Output

[0,1,-1]

Updated on: 30-Apr-2020

554 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements