Given an unweighted graph and a boolean array A[ ], where if the ith index of array A[ ] denotes if that node can be visited (0) or not (1). The task is to find the shortest path to reach (N – 1)th node from the 0th node. If it is not possible to reach, print -1.
Examples :
Input : N = 5, A[] = {0, 1, 0, 0, 0}, Edges = {{0, 1}, {0, 2}, {1, 4}, {2, 3}, {3, 4}} Output: 3 Explanation: There are two paths from 0th house to 4th house
Since a policeman is present at the 1st house, the only path that can be chosen is the 2nd path.
Input : N = 4, A[] = {0, 1, 1, 0}, Edges = {{0, 1}, {0, 2}, {1, 3}, {2, 3}} Output : -1
Approach: This problem is similar to finding the shortest path in an unweighted graph. Therefore, the problem can be solved using BFS.
Follow the steps below to solve the problem:
- Initialize an unordered_map, say adj to store the edges. The edge (a, b) must be excluded if there is a policeman either at node a or at node b.
- Initialize a variable, pathLength = 0.
- Initialize a vector of the boolean data type, say visited, to store whether a node is visited or not.
- Initialize an arraydist[0, 1, …., v-1] such that dist[i] stores the distance of vertex i from the root vertex
- Initialize a queue and push node 0 in it. Also, mark node 0 as visited.
- Iterate while the queue is not empty and the node N – 1 is not visited, pop the front element from the queue, and push all the elements into the queue that have an edge from the front element of the queue and are not visited and increase the distance of all these nodes by 1 + dist[q.top()].
- If the node (N – 1) is not visited, then print -1.
- Otherwise, print the distance of (N – 1)th node from the root node.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void createGraph(unordered_map< int , vector< int > >& adj,
int paths[][2], int A[], int N, int E)
{
for ( int i = 0; i < E; i++) {
if (!A[paths[i][0]] && !A[paths[i][1]]) {
adj[paths[i][0]].push_back(paths[i][1]);
}
}
}
int minPath( int paths[][2], int A[],
int N, int E)
{
if (A[0] == 1 || A[N - 1] == 1)
return -1;
unordered_map< int , vector< int > > adj;
createGraph(adj, paths, A, N, E);
vector< int > visited(N, 0);
int dist[N];
dist[0] = 0;
queue< int > q;
q.push(0);
visited[0] = 1;
while (!q.empty()) {
int temp = q.front();
q.pop();
for ( auto x : adj[temp]) {
if (!visited[x]) {
q.push(x);
visited[x] = 1;
dist[x] = dist[temp] + 1;
}
}
}
if (!visited[N - 1])
return -1;
else
return dist[N - 1];
}
int main()
{
int N = 5, E = 5;
int A[] = { 0, 1, 0, 0, 0 };
int paths[][2] = { { 0, 1 },
{ 0, 2 },
{ 1, 4 },
{ 2, 3 },
{ 3, 4 } };
cout << minPath(paths, A, N, E);
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
public class GFG {
static void
createGraph(HashMap<Integer, ArrayList<Integer> > adj,
int paths[][], int A[], int N, int E)
{
for ( int i = 0 ; i < E; i++) {
if (A[paths[i][ 0 ]] != 1
&& A[paths[i][ 1 ]] != 1 ) {
ArrayList<Integer> list = adj.getOrDefault(
paths[i][ 0 ], new ArrayList<>());
list.add(paths[i][ 1 ]);
adj.put(paths[i][ 0 ], list);
}
}
}
static int minPath( int paths[][], int A[], int N, int E)
{
if (A[ 0 ] == 1 || A[N - 1 ] == 1 )
return - 1 ;
HashMap<Integer, ArrayList<Integer> > adj
= new HashMap<>();
createGraph(adj, paths, A, N, E);
boolean visited[] = new boolean [N];
int dist[] = new int [N];
dist[ 0 ] = 0 ;
ArrayDeque<Integer> q = new ArrayDeque<>();
q.addLast( 0 );
visited[ 0 ] = true ;
while (!q.isEmpty()) {
int temp = q.removeFirst();
for ( int x : adj.getOrDefault(
temp, new ArrayList<>())) {
if (!visited[x]) {
q.addLast(x);
visited[x] = true ;
dist[x] = dist[temp] + 1 ;
}
}
}
if (!visited[N - 1 ])
return - 1 ;
else
return dist[N - 1 ];
}
public static void main(String[] args)
{
int N = 5 , E = 5 ;
int A[] = { 0 , 1 , 0 , 0 , 0 };
int paths[][] = {
{ 0 , 1 }, { 0 , 2 }, { 1 , 4 }, { 2 , 3 }, { 3 , 4 }
};
System.out.print(minPath(paths, A, N, E));
}
}
|
Python3
adj = {};
def createGraph(paths, A, N, E):
for i in range (E):
if ( not A[paths[i][ 0 ]] and not A[paths[i][ 1 ]]) :
if (paths[i][ 0 ] in adj):
tmp = adj[paths[i][ 0 ]];
tmp.append(paths[i][ 1 ]);
adj[paths[i][ 0 ]] = tmp;
else :
tmp = [];
tmp.append(paths[i][ 1 ]);
adj[paths[i][ 0 ]] = tmp;
def minPath(paths, A, N, E):
if (A[ 0 ] = = 1 or A[N - 1 ] = = 1 ):
return - 1 ;
createGraph(paths, A, N, E);
visited = [ 0 ] * N
dist = [ 0 ] * N
dist[ 0 ] = 0 ;
q = [];
q.append( 0 );
visited[ 0 ] = 1 ;
while ( len (q) ! = 0 ):
temp = q[ 0 ];
q.pop();
if (temp in adj):
for x in adj[temp] :
if ( not visited[x]):
q.append(x);
visited[x] = 1 ;
dist[x] = dist[temp] + 1 ;
if ( not visited[N - 1 ]):
return - 1 ;
else :
return dist[N - 1 ];
N = 5
E = 5 ;
A = [ 0 , 1 , 0 , 0 , 0 ];
paths = [ [ 0 , 1 ],
[ 0 , 2 ],
[ 1 , 4 ],
[ 2 , 3 ],
[ 3 , 4 ] ];
print (minPath(paths, A, N, E));
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
namespace GFG {
class Program {
static void Main( string [] args)
{
int N = 5, E = 5;
int [] A = { 0, 1, 0, 0, 0 };
int [][] paths
= { new int [] { 0, 1 }, new int [] { 0, 2 },
new int [] { 1, 4 }, new int [] { 2, 3 },
new int [] { 3, 4 } };
Console.WriteLine(MinPath(paths, A, N, E));
}
static void CreateGraph(Dictionary< int , List< int > > adj,
int [][] paths, int [] A, int N,
int E)
{
for ( int i = 0; i < E; i++) {
if (A[paths[i][0]] != 1
&& A[paths[i][1]] != 1) {
List< int > list
= adj.ContainsKey(paths[i][0])
? adj[paths[i][0]]
: new List< int >();
list.Add(paths[i][1]);
adj[paths[i][0]] = list;
}
}
}
static int MinPath( int [][] paths, int [] A, int N, int E)
{
if (A[0] == 1 || A[N - 1] == 1)
return -1;
Dictionary< int , List< int > > adj
= new Dictionary< int , List< int > >();
CreateGraph(adj, paths, A, N, E);
bool [] visited = new bool [N];
int [] dist = new int [N];
dist[0] = 0;
Queue< int > q = new Queue< int >();
q.Enqueue(0);
visited[0] = true ;
while (q.Count > 0) {
int temp = q.Dequeue();
if (adj.ContainsKey(temp)) {
foreach ( int x in adj[temp])
{
if (!visited[x]) {
q.Enqueue(x);
visited[x] = true ;
dist[x] = dist[temp] + 1;
}
}
}
}
if (!visited[N - 1])
return -1;
else
return dist[N - 1];
}
}
}
|
Javascript
<script>
var adj = new Map();
function createGraph(paths, A, N, E)
{
for ( var i = 0; i < E; i++) {
if (!A[paths[i][0]] && !A[paths[i][1]]) {
if (adj.has(paths[i][0]))
{
var tmp = adj.get(paths[i][0]);
tmp.push(paths[i][1]);
adj.set(paths[i][0], tmp);
}
else
{
var tmp = new Array();
tmp.push(paths[i][1]);
adj.set(paths[i][0], tmp);
}
}
}
}
function minPath(paths, A, N, E)
{
if (A[0] == 1 || A[N - 1] == 1)
return -1;
createGraph(paths, A, N, E);
var visited = Array(N).fill(0);
var dist = Array(N).fill(0);
dist[0] = 0;
var q = [];
q.push(0);
visited[0] = 1;
while (q.length!=0) {
var temp = q[0];
q.pop();
if (adj.has(temp))
{
for ( var x of adj.get(temp)) {
if (!visited[x]) {
q.push(x);
visited[x] = 1;
dist[x] = dist[temp] + 1;
}
}
}
}
if (!visited[N - 1])
return -1;
else
return dist[N - 1];
}
var N = 5, E = 5;
var A = [0, 1, 0, 0, 0 ];
var paths = [ [ 0, 1 ],
[ 0, 2 ],
[ 1, 4 ],
[ 2, 3 ],
[ 3, 4 ] ];
document.write(minPath(paths, A, N, E));
</script>
|
Time complexity: O (N + E) Auxiliary Space: O (N + E)
|