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 edgesdouble 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 codeint 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 approachimport 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 edgesstatic 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 codepublic 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 approachusing System;using System.Linq;using System.Collections.Generic;Â
public class GFG{Â
public static float inf = 1000000000;Â
// Function to return the smallest// product of edgespublic 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 codepublic 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 edgesfunction 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 codevar n = 3;var ed;// Input edgesed = [ [ [ 1, 2 ], 0.5 ],       [ [ 1, 3 ], 1.9 ],       [ [ 2, 3 ], 3 ] ];// Source and Destinationvar s = 1, d = 3;// Bellman fordvar 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!
