Given an undirected and unweighted graph of N nodes and M edges, the task is to count the minimum length paths between node 1 to N through each of the nodes. If there is doesn’t exist any such path, then print “-1”.
Note: The path can pass through a node any number of times.
Examples:
Input: N = 4, M= 4, edges = {{1, 2}, {2, 3}, {1, 3}, {2, 4}}
Output: 1 1 1 1
Explanation:
Total paths of minimum length from 1 to 4, passing from 1 is 1.
Total paths of minimum length from 1 to 4, passing from 2 is 1.
Total paths of minimum length from 1 to 4, passing from 3 is 1.
Total paths of minimum length from 1 to 4, passing from 4 is 1.Input: N = 5, M = 5, edges = {{1, 2}, {1, 4}, {1 3}, {2, 5}, {2, 4}}
Output: 1 1 0 1 1
Approach: The given problem can be solved by performing two BFS, one from node 1 excluding node N and another from node N excluding node 1 to find the minimum distance of all the nodes from 1 and N, and the product of both the minimum distances will be the total count of minimum length paths from 1 to N including the node. Follow the steps below to solve the problem:
- Initialize a queue, say queue1 to perform BFS from node 1 and a queue queue2 to perform BFS from node N.
- Initialize arrays, say dist[] to store the shortest distance and ways[] to count the number of ways to reach that node.
- Perform two BFS and perform the following steps in each case:
- Pop from the queue and store node in x and its distance in dis.
- If dist[x] is smaller than dis then continue.
- Traverse the adjacency list of x and for each child y, if dist[y] is greater than dis + 1 then update dist[y] equals dis + 1 and ways[y] equals ways[x]. Otherwise, if dist[y] equals dis +1 then add ways[x] to ways[y].
- Finally, iterate over the range N, and for each node print the count of minimum length paths as ways1[i]*ways2[i].
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
#define ll long long int // Function to calculate the distances // from node 1 to N void countMinDistance( int n, int m,
int edges[][2])
{ // Stores the number of edges
vector<ll> g[10005];
// Storing the edges in vector
for ( int i = 0; i < m; i++) {
int a = edges[i][0] - 1;
int b = edges[i][1] - 1;
g[a].push_back(b);
g[b].push_back(a);
}
// Initialize queue
queue<pair<ll, ll> > queue1;
queue1.push({ 0, 0 });
vector< int > dist(n, 1e9);
vector< int > ways1(n, 0);
dist[0] = 0;
ways1[0] = 1;
// BFS from 1st node using queue
while (!queue1.empty()) {
auto up = queue1.front();
// Pop from queue
queue1.pop();
int x = up.first;
int dis = up.second;
if (dis > dist[x])
continue ;
if (x == n - 1)
continue ;
// Traversing the adjacency list
for (ll y : g[x]) {
if (dist[y] > dis + 1) {
dist[y] = dis + 1;
ways1[y] = ways1[x];
queue1.push({ y, dis + 1 });
}
else if (dist[y] == dis + 1) {
ways1[y] += ways1[x];
}
}
}
// Initialize queue
queue<pair<ll, ll> > queue2;
queue2.push({ n - 1, 0 });
vector< int > dist1(n, 1e9);
vector< int > ways2(n, 0);
dist1[n - 1] = 0;
ways2[n - 1] = 1;
// BFS from last node
while (!queue2.empty()) {
auto up = queue2.front();
// Pop from queue
queue2.pop();
int x = up.first;
int dis = up.second;
if (dis > dist1[x])
continue ;
if (x == 0)
continue ;
// Traverse the adjacency list
for (ll y : g[x]) {
if (dist1[y] > dis + 1) {
dist1[y] = dis + 1;
ways2[y] = ways2[x];
queue2.push({ y, dis + 1 });
}
else if (dist1[y] == 1 + dis) {
ways2[y] += ways2[x];
}
}
}
// Print the count of minimum
// distance
for ( int i = 0; i < n; i++) {
cout << ways1[i] * ways2[i] << " " ;
}
} // Driver Code int main()
{ int N = 5, M = 5;
int edges[M][2] = {
{ 1, 2 }, { 1, 4 }, { 1, 3 },
{ 2, 5 }, { 2, 4 }
};
countMinDistance(N, M, edges);
return 0;
} |
import java.util.*;
// Tuple class definition class Tuple<X, Y> {
public final X x;
public final Y y;
// Constructor
public Tuple(X x, Y y)
{
this .x = x;
this .y = y;
}
// Getters
public X getX() { return x; }
public Y getY() { return y; }
} class GFG {
public static void countMinDistance( int n, int m,
int [][] edges)
{
// Stores the number of edges
List<Integer>[] g = new ArrayList[ 10005 ];
for ( int i = 0 ; i < 10005 ; i++) {
g[i] = new ArrayList<Integer>();
}
// Storing the edges in list
for ( int i = 0 ; i < m; i++) {
int a = edges[i][ 0 ] - 1 ;
int b = edges[i][ 1 ] - 1 ;
g[a].add(b);
g[b].add(a);
}
// Initialize queue
Queue<Tuple<Integer, Integer> > queue1
= new LinkedList<Tuple<Integer, Integer> >();
queue1.offer( new Tuple<Integer, Integer>( 0 , 0 ));
int [] dist = new int [n];
int [] ways1 = new int [n];
for ( int i = 0 ; i < n; i++) {
dist[i] = 1000000000 ;
}
dist[ 0 ] = 0 ;
ways1[ 0 ] = 1 ;
// BFS from 1st node using queue
while (queue1.size() > 0 ) {
Tuple<Integer, Integer> up = queue1.poll();
// Pop from queue
int x = up.x;
int dis = up.y;
if (dis > dist[x])
continue ;
if (x == n - 1 )
continue ;
// Traversing the adjacency list
for ( int y : g[x]) {
if (dist[y] > dis + 1 ) {
dist[y] = dis + 1 ;
ways1[y] = ways1[x];
queue1.offer(
new Tuple<Integer, Integer>(
y, dis + 1 ));
}
else if (dist[y] == dis + 1 ) {
ways1[y] += ways1[x];
}
}
}
// Initialize queue
Queue<Tuple<Integer, Integer> > queue2
= new LinkedList<Tuple<Integer, Integer> >();
queue2.offer( new Tuple<Integer, Integer>(n - 1 , 0 ));
int [] dist1 = new int [n];
int [] ways2 = new int [n];
for ( int i = 0 ; i < n; i++) {
dist1[i] = 1000000000 ;
}
dist1[n - 1 ] = 0 ;
ways2[n - 1 ] = 1 ;
// BFS from last node
while (queue2.size() > 0 ) {
Tuple<Integer, Integer> up = queue2.poll();
// Pop from queue
int x = up.x;
int dis = up.y;
if (dis > dist1[x])
continue ;
if (x == 0 )
continue ;
// Traverse the adjacency list
for ( int y : g[x]) {
if (dist1[y] > dis + 1 ) {
dist1[y] = dis + 1 ;
ways2[y] = ways2[x];
queue2.offer(
new Tuple<Integer, Integer>(
y, dis + 1 ));
}
else if (dist1[y] == 1 + dis) {
ways2[y] += ways2[x];
}
}
}
// Print the count of minimum distance
for ( int i = 0 ; i < n; i++) {
System.out.print(ways1[i] * ways2[i] + " " );
}
}
// Driver code
public static void main(String[] args)
{
int N = 5 , M = 5 ;
int edges[][] = new int [][] { new int [] { 1 , 2 },
new int [] { 1 , 4 },
new int [] { 1 , 3 },
new int [] { 2 , 5 },
new int [] { 2 , 4 } };
// Function call
countMinDistance(N, M, edges);
}
} // This code is contributed by phasing17. |
# Python 3 program for the above approach # Function to calculate the distances # from node 1 to N def countMinDistance(n, m, edges):
# Stores the number of edges
g = [[] for i in range ( 10005 )]
# Storing the edges in vector
for i in range (m):
a = edges[i][ 0 ] - 1
b = edges[i][ 1 ] - 1
g[a].append(b)
g[b].append(a)
# Initialize queue
queue1 = []
queue1.append([ 0 , 0 ])
dist = [ 1e9 for i in range (n)]
ways1 = [ 0 for i in range (n)]
dist[ 0 ] = 0
ways1[ 0 ] = 1
# BFS from 1st node using queue
while ( len (queue1)> 0 ):
up = queue1[ 0 ]
# Pop from queue
queue1 = queue1[: - 1 ]
x = up[ 0 ]
dis = up[ 1 ]
if (dis > dist[x]):
continue
if (x = = n - 1 ):
continue
# Traversing the adjacency list
for y in g[x]:
if (dist[y] > dis + 1 ):
dist[y] = dis + 1
ways1[y] = ways1[x]
queue1.append([y, dis + 1 ])
elif (dist[y] = = dis + 1 ):
ways1[y] + = ways1[x]
# Initialize queue
queue2 = []
queue2.append([n - 1 , 0 ])
dist1 = [ 1e9 for i in range (n)]
ways2 = [ 0 for i in range (n)]
dist1[n - 1 ] = 0
ways2[n - 1 ] = 1
# BFS from last node
while ( len (queue2)> 0 ):
up = queue2[ 0 ]
# Pop from queue
queue2 = queue2[: - 1 ]
x = up[ 0 ]
dis = up[ 1 ]
if (dis > dist1[x]):
continue
if (x = = 0 ):
continue
# Traverse the adjacency list
for y in g[x]:
if (dist1[y] > dis + 1 ):
dist1[y] = dis + 1
ways2[y] = ways2[x]
queue2.append([y, dis + 1 ])
elif (dist1[y] = = 1 + dis):
ways2[y] + = ways2[x]
# Print the count of minimum
# distance
ways1[n - 1 ] = 1
ways2[n - 1 ] = 1
for i in range (n):
print (ways1[i] * ways2[i],end = " " )
# Driver Code if __name__ = = '__main__' :
N = 5
M = 5
edges = [[ 1 , 2 ],[ 1 , 4 ],[ 1 , 3 ],[ 2 , 5 ],[ 2 , 4 ]]
countMinDistance(N, M, edges)
# This code is contributed by SURENDRA_GANGWAR.
|
using System;
using System.Collections.Generic;
class Program
{ public static void CountMinDistance( int n, int m, int [][] edges)
{
// Stores the number of edges
List< int >[] g = new List< int >[10005];
for ( int i = 0; i < 10005; i++)
{
g[i] = new List< int >();
}
// Storing the edges in list
for ( int i = 0; i < m; i++)
{
int a = edges[i][0] - 1;
int b = edges[i][1] - 1;
g[a].Add(b);
g[b].Add(a);
}
// Initialize queue
Queue<Tuple< int , int >> queue1 = new Queue<Tuple< int , int >>();
queue1.Enqueue( new Tuple< int , int >(0, 0));
int [] dist = new int [n];
int [] ways1 = new int [n];
for ( int i = 0; i < n; i++)
{
dist[i] = 1000000000;
}
dist[0] = 0;
ways1[0] = 1;
// BFS from 1st node using queue
while (queue1.Count > 0)
{
Tuple< int , int > up = queue1.Dequeue();
// Pop from queue
int x = up.Item1;
int dis = up.Item2;
if (dis > dist[x])
continue ;
if (x == n - 1)
continue ;
// Traversing the adjacency list
foreach ( int y in g[x])
{
if (dist[y] > dis + 1)
{
dist[y] = dis + 1;
ways1[y] = ways1[x];
queue1.Enqueue( new Tuple< int , int >(y, dis + 1));
}
else if (dist[y] == dis + 1)
{
ways1[y] += ways1[x];
}
}
}
// Initialize queue
Queue<Tuple< int , int >> queue2 = new Queue<Tuple< int , int >>();
queue2.Enqueue( new Tuple< int , int >(n - 1, 0));
int [] dist1 = new int [n];
int [] ways2 = new int [n];
for ( int i = 0; i < n; i++)
{
dist1[i] = 1000000000;
}
dist1[n - 1] = 0;
ways2[n - 1] = 1;
// BFS from last node
while (queue2.Count > 0)
{
Tuple< int , int > up = queue2.Dequeue();
// Pop from queue
int x = up.Item1;
int dis = up.Item2;
if (dis > dist1[x])
continue ;
if (x == 0)
continue ;
// Traverse the adjacency list
foreach ( int y in g[x])
{
if (dist1[y] > dis + 1)
{
dist1[y] = dis + 1;
ways2[y] = ways2[x];
queue2.Enqueue(Tuple.Create(y, dis + 1));
}
else if (dist1[y] == 1 + dis)
{
ways2[y] += ways2[x];
}
}
}
// Print the count of minimum
// distance
for ( int i = 0; i < n; i++)
{
Console.Write(ways1[i] * ways2[i] + " " );
}
} static void Main( string [] args)
{
int N = 5, M = 5;
int [][] edges = new int [][] {
new int [] { 1, 2 }, new int [] { 1, 4 }, new int [] { 1, 3 },
new int [] { 2, 5 }, new int [] { 2, 4 }
};
CountMinDistance(N, M, edges);
}
} |
<script> // Javascript program for the above approach // Function to calculate the distances // from node 1 to N function countMinDistance(n, m, edges) {
// Stores the number of edges
let g = new Array(10005).fill(0).map(() => []);
// Storing the edges in vector
for (let i = 0; i < m; i++) {
let a = edges[i][0] - 1;
let b = edges[i][1] - 1;
g[a].push(b);
g[b].push(a);
}
// Initialize queue
let queue1 = [];
queue1.push([0, 0]);
let dist = new Array(n).fill(1e9);
let ways1 = new Array(n).fill(0);
dist[0] = 0;
ways1[0] = 1;
// BFS from 1st node using queue
while (queue1.length > 0) {
let up = queue1[0];
// Pop from queue
queue1.pop();
let x = up[0];
let dis = up[1];
if (dis > dist[x]) continue ;
if (x == n - 1) continue ;
// Traversing the adjacency list
for (let y of g[x]) {
if (dist[y] > dis + 1) {
dist[y] = dis + 1;
ways1[y] = ways1[x];
queue1.push([y, dis + 1]);
} else if (dist[y] == dis + 1) ways1[y] += ways1[x];
}
}
// Initialize queue
let queue2 = [];
queue2.push([n - 1, 0]);
let dist1 = new Array(n).fill(1e9);
let ways2 = new Array(n).fill(0);
dist1[n - 1] = 0;
ways2[n - 1] = 1;
// BFS from last node
while (queue2.length > 0) {
let up = queue2[0];
// Pop from queue
queue2.pop();
let x = up[0];
let dis = up[1];
if (dis > dist1[x]) continue ;
if (x == 0) continue ;
// Traverse the adjacency list
for (let y of g[x]) {
if (dist1[y] > dis + 1) {
dist1[y] = dis + 1;
ways2[y] = ways2[x];
queue2.push([y, dis + 1]);
} else if (dist1[y] == 1 + dis) ways2[y] += ways2[x];
}
}
// Print the count of minimum
// distance
ways1[n - 1] = 1;
ways2[n - 1] = 1;
for (let i = 0; i < n; i++) document.write(ways1[i] * ways2[i] + " " );
} // Driver Code let N = 5; let M = 5; let edges = [ [1, 2],
[1, 4],
[1, 3],
[2, 5],
[2, 4],
]; countMinDistance(N, M, edges); // This code is contributed by gfgking </script> |
1 1 0 1 1
Time Complexity: O(N + M)
Auxiliary Space: O(N)