Given a directed graph with N nodes and E edges where the weight of each edge is > 0, also given a source S and a destination D. The task is to find the path with the minimum product of edges from S to D. If there is no path from S to D, then print -1.
Examples:
Input: N = 3, E = 3, Edges = {{{1, 2}, 0.5}, {{1, 3}, 1.9}, {{2, 3}, 3}}, S = 1, and D = 3
Output: 1.5
Explanation:
The shortest path will be 1->2->3
with value 0.5*3 = 1.5Input: N = 3, E = 3, Edges = {{{1, 2}, 0.5}, {{2, 3}, 0.5}, {{3, 1}, 0.5}}, S = 1, and D = 3
Output: cycle detected
Approach: The idea is to use the bellman ford algorithm. It is because Dijkstra’s algorithm cannot be used here as it works only with non-negative edges. It is because while multiplying values between [0-1), the product keeps decreasing indefinitely and 0 is returned finally.
Moreover, cycles need to be detected because if a cycle exists, the product of this cycle will indefinitely decrease the product to 0 and the product will tend to 0. For, simplicity, we will report such cycles.
The following steps can be followed to compute the result:
- Initialize an array, dis[] with initial value as ‘inf’ except dis[S] as 1.
- Run a loop from 1 – N-1. For each edge in the graph:
- dis[edge.second] = min(dis[edge.second], dis[edge.first]*weight(edge))
- Run another loop for each edge in the graph, if any edge exits with (dis[edge.second] > dis[edge.first]*weight(edge)), then cycle is detected.
- If dist[d] in infinity, return -1, else return dist[d].
Below is the implementation of the above approach:
// C++ implementation of the approach. #include <bits/stdc++.h> using namespace std;
double inf = std::
numeric_limits< double >::infinity();
// Function to return the smallest // product of edges double bellman( int s, int d,
vector<pair<pair< int , int >,
double > >
ed,
int n)
{ // If the source is equal
// to the destination
if (s == d)
return 0;
// Array to store distances
double dis[n + 1];
// Initialising the array
for ( int i = 1; i <= n; i++)
dis[i] = inf;
dis[s] = 1;
// Bellman ford algorithm
for ( int i = 0; i < n - 1; i++)
for ( auto it : ed)
dis[it.first.second] = min(dis[it.first.second],
dis[it.first.first]
* it.second);
// Loop to detect cycle
for ( auto it : ed) {
if (dis[it.first.second]
> dis[it.first.first] * it.second)
return -2;
}
// Returning final answer
if (dis[d] == inf)
return -1;
else
return dis[d];
} // Driver code int main()
{ int n = 3;
vector<pair<pair< int , int >, double > > ed;
// Input edges
ed = { { { 1, 2 }, 0.5 },
{ { 1, 3 }, 1.9 },
{ { 2, 3 }, 3 } };
// Source and Destination
int s = 1, d = 3;
// Bellman ford
double get = bellman(s, d, ed, n);
if (get == -2)
cout << "Cycle Detected" ;
else
cout << get;
} |
// Java implementation of the approach import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
class Pair<K, V>
{ K first;
V second;
public Pair(K first, V second)
{
this .first = first;
this .second = second;
}
} class GFG{
static final float inf = Float.POSITIVE_INFINITY;
// Function to return the smallest // product of edges static float bellman( int s, int d,
ArrayList<Pair<Pair<Integer,
Integer>, Float>> ed,
int n)
{ // If the source is equal
// to the destination
if (s == d)
return 0 ;
// Array to store distances
float [] dis = new float [n + 1 ];
// Initialising the array
Arrays.fill(dis, inf);
dis[s] = 1 ;
// Bellman ford algorithm
for ( int i = 0 ; i < n - 1 ; i++)
for (Pair<Pair<Integer, Integer>, Float> it : ed)
dis[it.first.second] = Math.min(dis[it.first.second],
dis[it.first.first] *
it.second);
// Loop to detect cycle
for (Pair<Pair<Integer, Integer>, Float> it : ed)
{
if (dis[it.first.second] >
dis[it.first.first] *
it.second)
return - 2 ;
}
// Returning final answer
if (dis[d] == inf)
return - 1 ;
else
return dis[d];
} // Driver code public static void main(String[] args)
{ int n = 3 ;
// Input edges
ArrayList<Pair<Pair<Integer,
Integer>, Float>> ed = new ArrayList<>(
Arrays.asList(
new Pair<Pair<Integer, Integer>, Float>(
new Pair<Integer, Integer>( 1 , 2 ), 0 .5f),
new Pair<Pair<Integer, Integer>, Float>(
new Pair<Integer, Integer>( 1 , 3 ), 1 .9f),
new Pair<Pair<Integer, Integer>, Float>(
new Pair<Integer, Integer>( 2 , 3 ), 3f)));
// Source and Destination
int s = 1 , d = 3 ;
// Bellman ford
float get = bellman(s, d, ed, n);
if (get == - 2 )
System.out.println( "Cycle Detected" );
else
System.out.println(get);
} } // This code is contributed by sanjeev2552 |
# Python3 implementation of the approach. import sys
inf = sys.maxsize;
# Function to return the smallest # product of edges def bellman(s, d, ed, n) :
# If the source is equal
# to the destination
if (s = = d) :
return 0 ;
# Array to store distances
dis = [ 0 ] * (n + 1 );
# Initialising the array
for i in range ( 1 , n + 1 ) :
dis[i] = inf;
dis[s] = 1 ;
# Bellman ford algorithm
for i in range (n - 1 ) :
for it in ed :
dis[it[ 1 ]] = min (dis[it[ 1 ]], dis[it[ 0 ]] * ed[it]);
# Loop to detect cycle
for it in ed :
if (dis[it[ 1 ]] > dis[it[ 0 ]] * ed[it]) :
return - 2 ;
# Returning final answer
if (dis[d] = = inf) :
return - 1 ;
else :
return dis[d];
# Driver code if __name__ = = "__main__" :
n = 3 ;
# Input edges
ed = { ( 1 , 2 ) : 0.5 ,
( 1 , 3 ) : 1.9 ,
( 2 , 3 ) : 3 };
# Source and Destination
s = 1 ; d = 3 ;
# Bellman ford
get = bellman(s, d, ed, n);
if (get = = - 2 ) :
print ( "Cycle Detected" );
else :
print (get);
# This code is contributed by AnkitRai01 |
// C# implementation of the approach using System;
using System.Linq;
using System.Collections.Generic;
public class GFG{
public static float inf = 1000000000;
// Function to return the smallest // product of edges public static float bellman( int s, int d,
List<KeyValuePair<KeyValuePair< int ,
int >, float >> ed,
int n)
{ // If the source is equal
// to the destination
if (s == d)
return 0;
// Array to store distances
float [] dis = Enumerable.Repeat(inf, n+1).ToArray();
dis[s] = 1;
// Bellman ford algorithm
for ( int i = 0; i < n - 1; i++)
foreach (KeyValuePair<KeyValuePair< int , int >, float > it in ed)
dis[it.Key.Value] = Math.Min(dis[it.Key.Value],
dis[it.Key.Key] *
it.Value);
// Loop to detect cycle
foreach (KeyValuePair<KeyValuePair< int , int >, float > it in ed)
{
if (dis[it.Key.Value] >
dis[it.Key.Key] *
it.Value)
return -2;
}
// Returning final answer
if (dis[d] == inf)
return -1;
else
return dis[d];
} // Driver code public static void Main( string [] args)
{ int n = 3;
// Input edges
List<KeyValuePair<KeyValuePair< int ,
int >, float >> ed = new List<KeyValuePair<KeyValuePair< int ,
int >, float >>(){
new KeyValuePair<KeyValuePair< int , int >, float >(
new KeyValuePair< int , int >(1, 2), 0.5f),
new KeyValuePair<KeyValuePair< int , int >, float >(
new KeyValuePair< int , int >(1, 3), 1.9f),
new KeyValuePair<KeyValuePair< int , int >, float >(
new KeyValuePair< int , int >(2, 3), 3f)};
// Source and Destination
int s = 1, d = 3;
// Bellman ford
float get = bellman(s, d, ed, n);
if ( get == -2)
Console.Write( "Cycle Detected" );
else
Console.Write( get );
} } // This code is contributed by rrrtnx. |
<script> // Javascript implementation of the approach. var inf = 1000000000;
// Function to return the smallest // product of edges function bellman(s, d, ed, n)
{ // If the source is equal
// to the destination
if (s == d)
return 0;
// Array to store distances
var dis = Array(n+1).fill(inf);
dis[s] = 1;
// Bellman ford algorithm
for ( var i = 0; i < n - 1; i++)
{
for ( var j =0 ; j< ed.length; j++)
{
dis[ed[j][0][1]] = Math.min(dis[ed[j][0][1]],
dis[ed[j][0][0]]
* ed[j][1]);
}
}
// Loop to detect cycle
for ( var it in ed) {
if (dis[it[0][1]]
> dis[it[0][0]] * it[1])
return -2;
}
// Returning final answer
if (dis[d] == inf)
return -1;
else
return dis[d];
} // Driver code var n = 3;
var ed;
// Input edges ed = [ [ [ 1, 2 ], 0.5 ], [ [ 1, 3 ], 1.9 ],
[ [ 2, 3 ], 3 ] ];
// Source and Destination var s = 1, d = 3;
// Bellman ford var get = bellman(s, d, ed, n);
if (get == -2)
document.write( "Cycle Detected" );
else document.write( get);
</script> |
1.5
Time complexity: O(E*V)
Auxiliary Space: O(V).