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++
// 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
// 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
# 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#
// 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. |
Javascript
<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).Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!