Given a directed graph with N nodes and E edges where the weight of each of the edge is > 1, 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}, 5}, {{1, 3}, 9}, {{2, 3}, 1}}, S = 1, and D = 3Â
Output: 5Â
The path with smallest product of edges will be 1->2->3Â
with product as 5*1 = 5.Input: N = 3, E = 3, Edges = {{{3, 2}, 5}, {{3, 3}, 9}, {{3, 3}, 1}}, S = 1, and D = 3Â
Output: -1Â
Approach: The idea is to use Dijkstra’s shortest path algorithm with a slight variation.Â
The following steps can be followed to compute the result:Â Â
- If the source is equal to the destination then return 0.
- Initialise a priority-queue pq with S and its weight as 1 and a visited array v[].
- While pq is not empty:Â
- Pop the top-most element from pq. Let’s call it as curr and its product of distance as dist.
- If curr is already visited then continue.
- If curr is equal to D then return dist.
- Iterate all the nodes adjacent to curr and push into pq (next and dist + gr[nxt].weight)
- return -1.
Below is the implementation of the above approach:Â Â
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; Â
// Function to return the smallest // product of edges double dijkstra( int s, int d,                 vector<vector<pair< int , double > > > gr) {     // If the source is equal     // to the destination     if (s == d)         return 0; Â
    // Initialise the priority queue     set<pair< int , int > > pq;     pq.insert({ 1, s }); Â
    // Visited array     bool v[gr.size()] = { 0 }; Â
    // While the priority-queue     // is not empty     while (pq.size()) { Â
        // Current node         int curr = pq.begin()->second; Â
        // Current product of distance         int dist = pq.begin()->first; Â
        // Popping the top-most element         pq.erase(pq.begin()); Â
        // If already visited continue         if (v[curr])             continue ; Â
        // Marking the node as visited         v[curr] = 1; Â
        // If it is a destination node         if (curr == d)             return dist; Â
        // Traversing the current node         for ( auto it : gr[curr])             pq.insert({ dist * it.second, it.first });     } Â
    // If no path exists     return -1; } Â
// Driver code int main() { Â Â Â Â int n = 3; Â
    // Graph as adjacency matrix     vector<vector<pair< int , double > > > gr(n + 1); Â
    // Input edges     gr[1].push_back({ 3, 9 });     gr[2].push_back({ 3, 1 });     gr[1].push_back({ 2, 5 }); Â
    // Source and destination     int s = 1, d = 3; Â
    // Dijkstra     cout << dijkstra(s, d, gr); Â
    return 0; } |
Java
// Java implementation of the approach import java.util.ArrayList; import java.util.PriorityQueue; Â
class Pair implements Comparable<Pair> { Â Â Â Â int first, second; Â
    public Pair( int first, int second)     {         this .first = first;         this .second = second;     } Â
    public int compareTo(Pair o)     {         if ( this .first == o.first)         {             return this .second - o.second;         }         return this .first - o.first;     } } Â
class GFG{ Â
// Function to return the smallest // xor sum of edges static int dijkstra( int s, int d,                     ArrayList<ArrayList<Pair>> gr) {          // If the source is equal     // to the destination     if (s == d)         return 0 ; Â
    // Initialise the priority queue     PriorityQueue<Pair> pq = new PriorityQueue<>();     pq.add( new Pair( 1 , s)); Â
    // Visited array     boolean [] v = new boolean [gr.size()]; Â
    // While the priority-queue     // is not empty     while (!pq.isEmpty())     {                  // Current node         Pair p = pq.poll();         int curr = p.second; Â
        // Current xor sum of distance         int dist = p.first; Â
        // If already visited continue         if (v[curr])             continue ; Â
        // Marking the node as visited         v[curr] = true ; Â
        // If it is a destination node         if (curr == d)             return dist; Â
        // Traversing the current node         for (Pair it : gr.get(curr))             pq.add( new Pair(dist ^ it.second, it.first));     } Â
    // If no path exists     return - 1 ; } Â
// Driver code public static void main(String[] args) { Â Â Â Â int n = 3 ; Â
    // Graph as adjacency matrix     ArrayList<ArrayList<Pair>> gr = new ArrayList<>();     for ( int i = 0 ; i < n + 1 ; i++)     {         gr.add( new ArrayList<Pair>());     } Â
    // Input edges     gr.get( 1 ).add( new Pair( 3 , 9 ));     gr.get( 2 ).add( new Pair( 3 , 1 ));     gr.get( 1 ).add( new Pair( 2 , 5 )); Â
    // Source and destination     int s = 1 , d = 3 ; Â
    System.out.println(dijkstra(s, d, gr)); } } Â
// This code is contributed by sanjeev2552 |
Python3
# Python3 implementation of the approach Â
# Function to return the smallest # product of edges def dijkstra(s, d, gr) : Â
    # If the source is equal     # to the destination     if (s = = d) :         return 0 ; Â
    # Initialise the priority queue     pq = [];     pq.append(( 1 , s ));          # Visited array     v = [ 0 ] * ( len (gr) + 1 ); Â
    # While the priority-queue     # is not empty     while ( len (pq) ! = 0 ) : Â
        # Current node         curr = pq[ 0 ][ 1 ]; Â
        # Current product of distance         dist = pq[ 0 ][ 0 ]; Â
        # Popping the top-most element         pq.pop(); Â
        # If already visited continue         if (v[curr]) :             continue ; Â
        # Marking the node as visited         v[curr] = 1 ; Â
        # If it is a destination node         if (curr = = d) :             return dist; Â
        # Traversing the current node         for it in gr[curr] :             if it not in pq :                 pq.insert( 0 ,( dist * it[ 1 ], it[ 0 ] )); Â
    # If no path exists     return - 1 ; Â
# Driver code if __name__ = = "__main__" : Â
    n = 3 ; Â
    # Graph as adjacency matrix     gr = {};          # Input edges     gr[ 1 ] = [( 3 , 9 ) ];     gr[ 2 ] = [ ( 3 , 1 ) ];     gr[ 1 ].append(( 2 , 5 ));     gr[ 3 ] = []; Â
    #print(gr);     # Source and destination     s = 1 ; d = 3 ;          # Dijkstra     print (dijkstra(s, d, gr)); Â
# This code is contributed by AnkitRai01 |
C#
//C# code for the above approach using System; using System.Collections.Generic; Â
class Pair : IComparable<Pair> { Â Â Â Â public int first, second; Â
    public Pair( int first, int second)     {         this .first = first;         this .second = second;     } Â
    public int CompareTo(Pair o)     {         if ( this .first == o.first)         {             return this .second - o.second;         }         return this .first - o.first;     } } Â
class GFG {     // Function to return the smallest     // xor sum of edges     static int Dijkstra( int s, int d,                         List<List<Pair>> gr)     {                  // If the source is equal         // to the destination         if (s == d)             return 0; Â
        // Initialise the priority queue         SortedSet<Pair> pq = new SortedSet<Pair>();         pq.Add( new Pair(1, s)); Â
        // Visited array         bool [] v = new bool [gr.Count]; Â
        // While the priority-queue         // is not empty         while (pq.Count != 0)         {                          // Current node             Pair p = pq.Min;             pq.Remove(p);             int curr = p.second; Â
            // Current xor sum of distance             int dist = p.first; Â
            // If already visited continue             if (v[curr])                 continue ; Â
            // Marking the node as visited             v[curr] = true ; Â
            // If it is a destination node             if (curr == d)                 return dist; Â
            // Traversing the current node             foreach (Pair it in gr[curr])                 pq.Add( new Pair(dist ^ it.second, it.first));         } Â
        // If no path exists         return -1;     } Â
    // Driver code     public static void Main( string [] args)     {         int n = 3; Â
        // Graph as adjacency matrix         List<List<Pair>> gr = new List<List<Pair>>();         for ( int i = 0; i < n + 1; i++)         {             gr.Add( new List<Pair>());         } Â
        // Input edges         gr[1].Add( new Pair(3, 9));         gr[2].Add( new Pair(3, 1));         gr[1].Add( new Pair(2, 5)); Â
        // Source and destination         int s = 1, d = 3; Â
        Console.WriteLine(Dijkstra(s, d, gr));     } } |
Javascript
<script> Â
// Javascript implementation of the approach Â
// Function to return the smallest // product of edges function dijkstra(s, d, gr) {     // If the source is equal     // to the destination     if (s == d)         return 0; Â
    // Initialise the priority queue     var pq = [];     pq.push([1, s]); Â
    // Visited array     var v = Array(gr.length).fill(0); Â
    // While the priority-queue     // is not empty     while (pq.length!=0) { Â
        // Current node         var curr = pq[0][1]; Â
        // Current product of distance         var dist = pq[0][0]; Â
        // Popping the top-most element         pq.shift(); Â
        // If already visited continue         if (v[curr])             continue ; Â
        // Marking the node as visited         v[curr] = 1; Â
        // If it is a destination node         if (curr == d)             return dist; Â
        // Traversing the current node         for ( var it of gr[curr])             pq.push([dist * it[1], it[0] ]);         pq.sort();     } Â
    // If no path exists     return -1; } Â
// Driver code var n = 3; Â
// Graph as adjacency matrix var gr = Array.from(Array(n + 1), ()=> Array()); Â
// Input edges gr[1].push([3, 9]); gr[2].push([3, 1]); gr[1].push([2, 5]); Â
// Source and destination var s = 1, d = 3; Â
// Dijkstra document.write(dijkstra(s, d, gr)); Â
// This code is contributed by rrrtnx. </script> |
5
Â
Time complexity: O((E + V) logV)
Auxiliary Space: O(V).Â
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!