Open In App

Find the maximum product of edge weights in Graph

Improve
Improve
Like Article
Like
Save
Share
Report

Given a directed, weighted graph with n nodes and e edges, the task is to find the maximum product of edge weights in any path starting from node 1 and ending at node n.  

Note: A path is a sequence of nodes starting and ending at particular nodes. The Graph does not contain loops and parallel edges.

Example:

Input: 

 

Output: 224
Explanation: 7 * 4 * 8 = 224, as we have to travel from 1 to n i.e., 1 to 5 = > 1 – > 4 – > 2  – > 5

Approach: This can be solved with the following idea:

The idea is to apply the Dijkstra algorithm and change the meaning of the array which in the original algorithm used to store the value of the minimum sum of edge weights required to reach the current node to the maximum product of edge weights among all possible paths to reach the current node. We will update the update logic of Dijkstra to store the maximum product of edges in the array.

Steps involved in the implementation of code:

  • Initialize a priority queue (pq) ( Max heap ) of pair ( Pair as it contains the first value of the maximum edge encountered and second current node).
  • Insert into the priority queue a pair (1, 1) -> (1) denoting starting node 1 ( No edges encountered, and as we are going to do multiplication we need to initialize the first node with value 1)
  • Initialize an array of size = no. of nodes, denoting the maximum edge weight encountered from node 1 to the current node.
  • Run a while loop while (pq.size() > 0): 
    • Pair p = pq.top() ; 
    • pq.pop() (removing top element from the priority queue) 
    • for (nodes in adjacency list): 
      • update logic: update the array of the maximum product if the product of the current edge weight and previous node maximum product is greater than the current node maximum product value.
  • Run a loop on the array to find the maximum answer.

Below is the implementation of the above approach:

C++




// C++ Implementation of the above code
#include <bits/stdc++.h>
using namespace std;
 
// Function to find maximum weight
// of graphfrom 1 to n
int max_product_of_edges_in_path(
    int n, vector<vector<int> >& roads)
{
 
    // Declaring adjacency list
    vector<vector<pair<int, int> > > adj(n + 1);
 
    // Construction of adjacency list using
    // the information of edges
    for (int i = 0; i < roads.size(); i++) {
 
        adj[roads[i][0]].push_back(
            { roads[i][1], roads[i][2] });
 
        // Directed graph : edge from
        // roads[i][0] -> roads[i][1]
        // of edge weight roads[i][2]
    }
 
    priority_queue<pair<int, int> > pq;
 
    // Normal dijkstra
    pq.push({ 1, 1 });
 
    vector<int> max_product(n + 1, -1);
 
    max_product[1] = 1;
 
    while (!pq.empty()) {
        pair<int, int> p = pq.top();
        pq.pop();
        if (max_product[p.second] > p.first)
            continue;
 
        // Reduce extra iterations
        // as in dijkstra
        for (auto it : adj[p.second]) {
 
            // Update logic similar to
            // dijkstra but with
            // conditions changed
            if (p.first * it.second
                > max_product[it.first]) {
                max_product[it.first] = p.first * it.second;
                pq.push(
                    { max_product[it.first], it.first });
            }
        }
    }
    return max_product[n];
}
 
// Driver code
int main()
{
 
    int n = 5;
    vector<vector<int> > edges;
 
    edges.push_back({ 1, 2, 5 });
    edges.push_back({ 1, 3, 6 });
    edges.push_back({ 1, 4, 7 });
    edges.push_back({ 4, 2, 4 });
    edges.push_back({ 2, 5, 8 });
 
    // Function call
    cout << max_product_of_edges_in_path(n, edges) << "\n";
    return 0;
}


Java




//Java Algorithm for the above approach
 
import java.util.*;
 
public class GFG {
 
    // Implementing Pair class
    public static class Pair implements Comparable<Pair> {
        int first;
        int second;
        Pair(int first, int second)
        {
            this.first = first;
            this.second = second;
        }
        public int compareTo(Pair ob)
        {
            if (this.first == ob.first) {
                return this.second - ob.second;
            }
            return this.first - ob.first;
        }
    }
 
    // Function to find maximum weight
    // of graphfrom 1 to n
    public static int max_product_of_edges_in_path(
        int n, ArrayList<ArrayList<Integer> > roads)
    {
        // Declaring adjacency list
        ArrayList<Pair>[] adj = new ArrayList[n + 1];
        for (int i = 0; i < n + 1; i++) {
            adj[i] = new ArrayList<>();
        }
 
        // Construction of adjacency list using
        // the information of edges
        for (int i = 0; i < roads.size(); i++) {
 
            adj[roads.get(i).get(0)].add(new Pair(
                roads.get(i).get(1), roads.get(i).get(2)));
            ;
 
            // Directed graph : edge from
            // roads[i][0] -> roads[i][1]
            // of edge weight roads[i][2]
        }
 
        PriorityQueue<Pair> pq = new PriorityQueue<>();
 
        // Normal dijkstra
        pq.add(new Pair(1, 1));
        int[] max_product = new int[n + 1];
        Arrays.fill(max_product, -1);
        max_product[1] = 1;
 
        while (!pq.isEmpty()) {
            Pair p = pq.remove();
            if (max_product[p.second] > p.first)
                continue;
 
            // Reduce extra iterations
            // as in dijkstra
            for (Pair it : adj[p.second]) {
 
                // Update logic similar to
                // dijkstra but with
                // conditions changed
                if (p.first * it.second
                    > max_product[it.first]) {
                    max_product[it.first]
                        = p.first * it.second;
                    pq.add(new Pair(max_product[it.first],
                                    it.first));
                }
            }
        }
        return max_product[n];
    }
    // Driver Code
    public static void main(String[] args)
    {
        int n = 5;
        ArrayList<ArrayList<Integer> > edges
            = new ArrayList<ArrayList<Integer> >();
 
        edges.add(new ArrayList<Integer>() {
            {
                add(1);
                add(2);
                add(5);
            }
        });
        edges.add(new ArrayList<Integer>() {
            {
                add(1);
                add(3);
                add(6);
            }
        });
        edges.add(new ArrayList<Integer>() {
            {
                add(1);
                add(4);
                add(7);
            }
        });
        edges.add(new ArrayList<Integer>() {
            {
                add(4);
                add(2);
                add(4);
            }
        });
        edges.add(new ArrayList<Integer>() {
            {
                add(2);
                add(5);
                add(8);
            }
        });
 
        // Function Call
        System.out.println(
            max_product_of_edges_in_path(n, edges));
    }
}


Python




# python Algorithm for the above approach
import heapq
 
def max_product_of_edges_in_path(n, roads):
    # Declaring adjacency list
    adj = [[] for _ in range(n+1)]
 
    # Construction of adjacency list using the information of edges
    for road in roads:
        adj[road[0]].append((road[1], road[2]))
        # Directed graph: edge from road[0] -> road[1] of edge weight road[2]
 
    pq = []  # priority queue using heapq module
 
    # Normal Dijkstra's
    heapq.heappush(pq, (1, 1))
 
    max_product = [-1] * (n+1)
    max_product[1] = 1
 
    while pq:
        p = heapq.heappop(pq)
        if max_product[p[1]] > p[0]:
            continue
 
        # Reduce extra iterations as in Dijkstra's
        for it in adj[p[1]]:
            # Update logic similar to Dijkstra's but with conditions changed
            if p[0] * it[1] > max_product[it[0]]:
                max_product[it[0]] = p[0] * it[1]
                heapq.heappush(pq, (max_product[it[0]], it[0]))
 
    return max_product[n]
 
 
# Driver code
if __name__ == '__main__':
    n = 5
    edges = [
        [1, 2, 5],
        [1, 3, 6],
        [1, 4, 7],
        [4, 2, 4],
        [2, 5, 8]
    ]
 
    # Function call
    print(max_product_of_edges_in_path(n, edges))
 
  # This code is generated by Chetan Bargal


C#




// C# code for the approach
 
using System;
using System.Collections.Generic;
 
public class Solution {
      // Function to find maximum weight
    // of graphfrom 1 to n
    public int MaxProductOfEdgesInPath(int n, int[][] roads) {
        // Declaring adjacency list
        List<int[]>[] adj = new List<int[]>[n+1];
        for (int i = 0; i <= n; i++) {
            adj[i] = new List<int[]>();
        }
 
        // Construction of adjacency list using the information of edges
        foreach (int[] road in roads) {
            adj[road[0]].Add(new int[] { road[1], road[2] });
            // Directed graph: edge from road[0] -> road[1] of edge weight road[2]
        }
 
        // Priority queue using SortedSet
        SortedSet<Tuple<int, int>> pq = new SortedSet<Tuple<int, int>>();
 
        // Normal Dijkstra's
        pq.Add(new Tuple<int, int>(1, 1));
 
        int[] maxProduct = new int[n+1];
        for (int i = 0; i <= n; i++) {
            maxProduct[i] = -1;
        }
        maxProduct[1] = 1;
 
        while (pq.Count > 0) {
            Tuple<int, int> p = pq.Max;
            pq.Remove(p);
            if (maxProduct[p.Item2] > p.Item1) {
                continue;
            }
 
            // Reduce extra iterations as in Dijkstra's
            foreach (int[] it in adj[p.Item2]) {
                // Update logic similar to Dijkstra's but with conditions changed
                if (p.Item1 * it[1] > maxProduct[it[0]]) {
                    maxProduct[it[0]] = p.Item1 * it[1];
                    pq.Add(new Tuple<int, int>(maxProduct[it[0]], it[0]));
                }
            }
        }
 
        return maxProduct[n];
    }
}
 
// Driver code
public class GFG {
    static void Main(string[] args) {
        int n = 5;
        int[][] edges = {
            new int[] {1, 2, 5},
            new int[] {1, 3, 6},
            new int[] {1, 4, 7},
            new int[] {4, 2, 4},
            new int[] {2, 5, 8}
        };
 
        // Function call
        Solution solution = new Solution();
        Console.WriteLine(solution.MaxProductOfEdgesInPath(n, edges));
    }
}


Javascript




// Javascript implementation of the above code
 
// Function to find maximum weight
// of graph from 1 to n
function maxProductOfEdgesInPath(n, roads) {
  // Declaring adjacency list
  const adj = Array(n + 1)
    .fill()
    .map(() => []);
  // Construction of adjacency list using
  // the information of edges
  for (let i = 0; i < roads.length; i++) {
    adj[roads[i][0]].push([roads[i][1], roads[i][2]]);
    // Directed graph: edge from
    // roads[i][0] -> roads[i][1]
    // of edge weight roads[i][2]
  }
  const pq = [];
  // Normal dijkstra
  pq.push([1, 1]);
  const maxProduct = Array(n + 1).fill(-1);
  maxProduct[1] = 1;
  while (pq.length > 0) {
    const [pFirst, pSecond] = pq.shift();
    if (maxProduct[pSecond] > pFirst) continue;
    // Reduce extra iterations
    // as in dijkstra
    for (const [itFirst, itSecond] of adj[pSecond]) {
      // Update logic similar to
      // dijkstra but with
      // conditions changed
      if (pFirst * itSecond > maxProduct[itFirst]) {
        maxProduct[itFirst] = pFirst * itSecond;
        pq.push([maxProduct[itFirst], itFirst]);
      }
    }
  }
  return maxProduct[n];
}
// Driver code
const n = 5;
const edges = [
  [1, 2, 5],
  [1, 3, 6],
  [1, 4, 7],
  [4, 2, 4],
  [2, 5, 8],
];
// Function call
console.log(maxProductOfEdgesInPath(n, edges));


Output

224


Time complexity: O(NLogN)
Auxiliary Space: O(N)



Last Updated : 10 Jul, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads