Program to Find Out the Minimum Cost Possible from Weighted Graph in Python


Suppose we have a 2D list of integers called edges which are a representation of an undirected graph. Every row in the input represents an edge [u, v, w] meaning nodes u and v are connected and the edge has the weight w. The graph consists of n nodes from 0 to n-1.

The cost of a path is defined here as the product of the number of edges and the maximum weight for any edge in the path. We have to find out the minimum cost possible from node 0 to node n-1, or we declare the answer as -1 if no such path exists.

So, if the input is like edges = [
   [0, 2, 100],
   [1, 2, 200],
   [1, 3, 100],
   [2, 3, 300]
], then the output will be 600

To solve this, we will follow these steps −

  • graph := a new map

  • weights := a new map

  • max_weight := 0

  • N := 0

  • for each u, v, w in edges, do

    • insert v at the end of graph[u]

    • insert u at the end of graph[v]

    • weights[u, v] := w

    • weights[v, u] := w

    • N := maximum of N, u + 1, v + 1

    • max_weight := maximum of max_weight, w

  • result := infinity

  • while max_weight >= 0, do

    • d, weight := bfs(0, max_weight)

    • if d >= 0, then

      • result := minimum of result, d * weight

      • max_weight := weight - 1

    • otherwise,

      • terminate the loop

  • return result if result < infinity otherwise -1

  • Define a function bfs() . This will take root, weight_cap

    • target := N - 1

    • Q := a deque containing root, 0, 0

    • visited := [False] * N

    • visited[0] := True

    • while Q is not empty, do

      • v, d, current_weight := delete last element from Q

      • if v is same as N - 1, then

        • return d, current_weight

      • for each w in graph[v], do

        • if visited[w] is non-zero, then

          • continue the next iteration

        • new_weight := weights[v, w]

        • if new_weight <= weight_cap, then

          • visited[w] := True

          • add (w, d + 1, maximum of (current_weight, new_weight)) at the left of Q

    • return -1, -1

Example 

Let us see the following implementation to get better understanding −

 Live Demo

from collections import defaultdict, deque
class Solution:
   def solve(self, edges):
      graph = defaultdict(list)
      weights = {}
      max_weight = 0
      N = 0
      for u, v, w in edges:
         graph[u].append(v)
         graph[v].append(u)
         weights[u, v] = w
         weights[v, u] = w
         N = max(N, u + 1, v + 1)
         max_weight = max(max_weight, w)
      def bfs(root, weight_cap):
         target = N - 1
         Q = deque([(root, 0, 0)])
         visited = [False] * N
         visited[0] = True
         while Q:
            v, d, current_weight = Q.pop()
            if v == N - 1:
               return d, current_weight
            for w in graph[v]:
               if visited[w]:
                  continue
               new_weight = weights[v, w]
               if new_weight <= weight_cap:
                  visited[w] = True
                     zQ.appendleft((w, d + 1, max(current_weight, new_weight)))
         return -1, -1
      result = float("inf")
      while max_weight >= 0:
         d, weight = bfs(0, max_weight)
         if d >= 0:
            result = min(result, d * weight)
            max_weight = weight - 1
         else:
            break
      return result if result < float("inf") else -1

ob = Solution()
print (ob.solve( [
   [0, 2, 100],
   [1, 2, 200],
   [1, 3, 100],
   [2, 3, 300]
]))

Input

[
   [0, 2, 100],
   [1, 2, 200],
   [1, 3, 100],
   [2, 3, 300]
]

Output

600

Updated on: 23-Dec-2020

573 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements