Consider a directed graph of ‘N’ nodes where each node is labeled from ‘0’ to ‘N – 1’. Each edge of the graph is either ‘red’ or ‘blue’ colored. The graph may contain self-edges or parallel edges. You are given two arrays, ‘redEdges’ and ‘blueEdges’, whose each element is of the form [i, j], denoting an edge from node ‘i’ to node ‘j’ of the respective color. Your task is to compute an array ‘answer’ of size ‘N’, where ‘answer[i]’ stores the shortest path length from node ‘0’ to node ‘i’ such that the edges along the path have alternate colors. If there is no such path from node ‘0’ to ‘i’, then ‘answer[i] = -1’.
Examples:
Input: n = 3, redEdges = {{0, 0}}, blueEdges = {{0, 0}, {0, 1}} Output: {0 1} Explanation: For Node 0: The shortest path is to stay at Node 0 with a length of 0. For Node 1: The shortest path is to move from Node 0 to Node 1 with a length of 1. For Node 2: There is no direct edge to Node 2, so the path length is -1 (impossible). Therefore, the ‘answer’ array is [0, 1] which represents the shortest alternate colored paths for each node and node 2 produces -1 so we will not consider it.
Input: n = 3, redEdges = {{1, 0}}, blueEdges = {{0, 1}, {0, 2}} Output: {0 1 1} Explanation: For Node 0: The shortest path is to stay at Node 0 with a length of 0. For Node 1: The shortest path is to move from Node 0 to Node 1 with a length of 1. For Node 2: The shortest path is to move from Node 0 to Node 2 with a length of 1. The array is [0, 1, 1], representing the shortest alternate colored paths for each node in this graph.
Shortest alternate colored path using BFS:
The approach to find the Shortest alternate colored path by using Breadth-first search algorithm.
Steps were taken to solve the problem.
- Two arrays of vectors, graph[2][n], represent the edges of red and blue colors. The first loop populates the red edges, and the second loop populates the blue edges.
- A 2D vector, distances, is created to store the shortest distances for each node (indexed by node and color). All distances are initialized to 2 * n, and the source node is set to have a distance of 0 for both colors.
- A queue, bfsQueue, is used for BFS traversal. It starts with the source node for both red and blue colors.
- The BFS loop processes nodes from the queue, exploring neighbors with alternate colors. For each neighbor, it checks if the distance from the source node of the opposite color can be reduced. If so, it updates the distance and adds the neighbor to the queue with the alternate color.
- Finally, the code computes the result array. For each node, it calculates the minimum distance between the red and blue colors and sets it as the result. If a node’s distance is still 2 * n, it means there’s no valid path, so it’s set to -1.
Below is the C++ implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > shortestAlternateColoredPath(
int n, vector<vector< int > >& redEdges,
vector<vector< int > >& blueEdges)
{
vector< int > graph[2][n];
for ( int i = 0; i < redEdges.size(); i++) {
graph[0][redEdges[i][0]].push_back(redEdges[i][1]);
}
for ( int i = 0; i < blueEdges.size(); i++) {
graph[1][blueEdges[i][0]].push_back(
blueEdges[i][1]);
}
vector<vector< int > > distances(n,
vector< int >(2, 2 * n));
distances[0][0] = distances[0][1] = 0;
queue<pair< int , int > > bfsQueue;
bfsQueue.push(make_pair(0, 0));
bfsQueue.push(make_pair(0, 1));
while (!bfsQueue.empty()) {
int current = bfsQueue.front().first;
int color = bfsQueue.front().second;
bfsQueue.pop();
for ( int i = 0;
i < graph[1 - color][current].size(); i++) {
int next = graph[1 - color][current][i];
if (distances[next][1 - color]
> distances[current][color] + 1) {
distances[next][1 - color]
= distances[current][color] + 1;
bfsQueue.push(make_pair(next, 1 - color));
}
}
}
vector< int > result(n);
for ( int i = 0; i < n; i++) {
result[i] = min(distances[i][0], distances[i][1]);
if (result[i] == 2 * n)
result[i] = -1;
}
return result;
}
int main()
{
int n = 3;
vector<vector< int > > redEdges = { { 1, 0 } };
vector<vector< int > > blueEdges = { { 0, 1 }, { 0, 2 } };
vector< int > result = shortestAlternateColoredPath(
n, redEdges, blueEdges);
cout << "Shortest Alternate Colored Path for each node:"
<< endl;
for ( int i = 0; i < n; i++) {
cout << result[i] << " ";
}
return 0;
}
|
Java
import java.util.*;
public class GFG {
public static List<Integer>
shortestAlternateColoredPath(
int n, List<List<Integer> > redEdges,
List<List<Integer> > blueEdges)
{
List<List<Integer> >[] graph = new ArrayList[ 2 ];
for ( int i = 0 ; i < 2 ; i++) {
graph[i] = new ArrayList<>();
for ( int j = 0 ; j < n; j++) {
graph[i].add( new ArrayList<>());
}
}
for (List<Integer> redEdge : redEdges) {
graph[ 0 ]
.get(redEdge.get( 0 ))
.add(redEdge.get( 1 ));
}
for (List<Integer> blueEdge : blueEdges) {
graph[ 1 ]
.get(blueEdge.get( 0 ))
.add(blueEdge.get( 1 ));
}
int [][] distances = new int [n][ 2 ];
for ( int [] distance : distances) {
Arrays.fill(distance, 2 * n);
}
distances[ 0 ][ 0 ] = distances[ 0 ][ 1 ] = 0 ;
Queue< int []> bfsQueue = new LinkedList<>();
bfsQueue.offer( new int [] { 0 , 0 });
bfsQueue.offer( new int [] { 0 , 1 });
while (!bfsQueue.isEmpty()) {
int [] current = bfsQueue.poll();
int currentNode = current[ 0 ];
int color = current[ 1 ];
for ( int next :
graph[ 1 - color].get(currentNode)) {
if (distances[next][ 1 - color]
> distances[currentNode][color] + 1 ) {
distances[next][ 1 - color]
= distances[currentNode][color] + 1 ;
bfsQueue.offer(
new int [] { next, 1 - color });
}
}
}
List<Integer> result = new ArrayList<>();
for ( int i = 0 ; i < n; i++) {
result.add(
Math.min(distances[i][ 0 ], distances[i][ 1 ]));
if (result.get(i) == 2 * n)
result.set(i, - 1 );
}
return result;
}
public static void main(String[] args)
{
int n = 3 ;
List<List<Integer> > redEdges
= Arrays.asList(Arrays.asList( 1 , 0 ));
List<List<Integer> > blueEdges = Arrays.asList(
Arrays.asList( 0 , 1 ), Arrays.asList( 0 , 2 ));
List<Integer> result = shortestAlternateColoredPath(
n, redEdges, blueEdges);
System.out.println(
"Shortest Alternate Colored Path for each node:" );
for ( int value : result) {
System.out.print(value + " " );
}
}
}
|
Python3
from collections import deque
def shortest_alternate_colored_path(n, red_edges, blue_edges):
graph = [[[] for j in range (n)] for i in range ( 2 )]
for i in range ( len (red_edges)):
graph[ 0 ][red_edges[i][ 0 ]].append(red_edges[i][ 1 ])
for i in range ( len (blue_edges)):
graph[ 1 ][blue_edges[i][ 0 ]].append(blue_edges[i][ 1 ])
distances = [[ 2 * n] * 2 for _ in range (n)]
distances[ 0 ][ 0 ] = distances[ 0 ][ 1 ] = 0
bfs_queue = deque([( 0 , 0 ), ( 0 , 1 )])
while bfs_queue:
current, color = bfs_queue.popleft()
for i in range ( len (graph[ 1 - color][current])):
next_node = graph[ 1 - color][current][i]
if distances[next_node][ 1 - color] > distances[current][color] + 1 :
distances[next_node][ 1 - color] = distances[current][color] + 1
bfs_queue.append((next_node, 1 - color))
result = [ min (distances[i][ 0 ], distances[i][ 1 ]) if min (
distances[i]) ! = 2 * n else - 1 for i in range (n)]
return result
if __name__ = = "__main__" :
n = 3
red_edges = [[ 1 , 0 ]]
blue_edges = [[ 0 , 1 ], [ 0 , 2 ]]
result = shortest_alternate_colored_path(n, red_edges, blue_edges)
print ( "Shortest Alternate Colored Path for each node:" )
for i in range (n):
print (result[i], end = " " )
|
C#
using System;
using System.Collections.Generic;
public class GFG {
public static List< int >
ShortestAlternateColoredPath( int n,
List<List< int > > redEdges,
List<List< int > > blueEdges)
{
List< int >[] graph = new List< int >[ 2 * n ];
for ( int i = 0; i < 2 * n; i++) {
graph[i] = new List< int >();
}
foreach ( var edge in redEdges)
{
graph[edge[0]].Add(edge[1]);
}
foreach ( var edge in blueEdges)
{
graph[edge[0] + n].Add(edge[1] + n);
}
int [, ] distances = new int [n, 2];
for ( int i = 0; i < n; i++) {
distances[i, 0] = distances[i, 1] = 2 * n;
}
distances[0, 0] = distances[0, 1] = 0;
Queue<Tuple< int , int > > bfsQueue
= new Queue<Tuple< int , int > >();
bfsQueue.Enqueue( new Tuple< int , int >(0, 0));
bfsQueue.Enqueue( new Tuple< int , int >(0, 1));
while (bfsQueue.Count > 0) {
var current = bfsQueue.Dequeue();
int currentNode = current.Item1;
int color = current.Item2;
foreach (
var next in
graph[n * (1 - color) + currentNode])
{
if (distances[next % n, 1 - color]
> distances[currentNode, color] + 1) {
distances[next % n, 1 - color]
= distances[currentNode, color] + 1;
bfsQueue.Enqueue( new Tuple< int , int >(
next % n, 1 - color));
}
}
}
List< int > result = new List< int >();
for ( int i = 0; i < n; i++) {
result.Add(
Math.Min(distances[i, 0], distances[i, 1]));
if (result[i] == 2 * n)
result[i] = -1;
}
return result;
}
public static void Main( string [] args)
{
int n = 3;
List<List< int > > redEdges
= new List<List< int > >{ new List< int >{ 1, 0 } };
List<List< int > > blueEdges
= new List<List< int > >{ new List< int >{ 0, 1 },
new List< int >{ 0, 2 } };
List< int > result = ShortestAlternateColoredPath(
n, redEdges, blueEdges);
Console.WriteLine(
"Shortest Alternate Colored Path for each node:" );
foreach ( var item in result)
{
Console.Write(item + " " );
}
Console.WriteLine();
}
}
|
Javascript
class GFG {
static shortestAlternateColoredPath(n, redEdges, blueEdges) {
const graph = [[], []];
for (let i = 0; i < n; i++) {
graph[0].push([]);
graph[1].push([]);
}
for (const redEdge of redEdges) {
graph[0][redEdge[0]].push(redEdge[1]);
}
for (const blueEdge of blueEdges) {
graph[1][blueEdge[0]].push(blueEdge[1]);
}
const distances = Array.from({ length: n }, () => Array(2).fill(2 * n));
distances[0][0] = distances[0][1] = 0;
const bfsQueue = [];
bfsQueue.push([0, 0]);
bfsQueue.push([0, 1]);
while (bfsQueue.length > 0) {
const current = bfsQueue.shift();
const currentNode = current[0];
const color = current[1];
for (const next of graph[1 - color][currentNode]) {
if (distances[next][1 - color] > distances[currentNode][color] + 1) {
distances[next][1 - color] = distances[currentNode][color] + 1;
bfsQueue.push([next, 1 - color]);
}
}
}
const result = [];
for (let i = 0; i < n; i++) {
result.push(Math.min(distances[i][0], distances[i][1]));
if (result[i] === 2 * n) {
result[i] = -1;
}
}
return result;
}
static main() {
const n = 3;
const redEdges = [[1, 0]];
const blueEdges = [[0, 1], [0, 2]];
const result = this .shortestAlternateColoredPath(n, redEdges, blueEdges);
console.log( "Shortest Alternate Colored Path for each node:" );
console.log(result.join( " " ));
}
}
GFG.main();
|
Output
Shortest Alternate Colored Path for each node:
0 1 1
Time Complexity: O(N + RLEN + BLEN), where ‘RLEN’ is the number of red edges, and ‘BLEN’ is the number of blue edges, and ‘N’ is the number of nodes. Auxiliary space: O(N + RLEN + BLEN), where ‘RLEN’ is the number of red edges, and ‘BLEN’ is the number of blue edges, and ‘N’ is the number of nodes.
|