Path with smallest product of edges with weight>0

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 sysinf = 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 zambiatek!



