Path with smallest product of edges with weight >= 1

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:
    1. Pop the top-most element from pq. Let’s call it as curr and its product of distance as dist.
    2. If curr is already visited then continue.
    3. If curr is equal to D then return dist.
    4. 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


Output:

5

Time complexity: O((E + V) logV)

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01