Program to find out if a vertex in an undirected graph has a lesser cost path in Python

Suppose, we are given a weighted, undirected graph. We have to implement a function query that takes two vertices and a cost 'limit' as input and checks if there exists a path with cost less than or equal to the given limit. We return true if such a path exists, otherwise we return false.

So, if the input is like ?

and the queries are (0, 2, 10), (3, 1, 30), (4, 3, 30).

then the output will be ?

False
True
True

The result of the first query is False because there is no path between vertex 0 to 2 with cost ≤ 10.

The result of the second query is True because there is a path between vertex 3 to 1 with cost 10, which is less than 30.

The result of the third query is True because there is a path between vertex 4 to 3 with cost 30, which equals the limit.

Algorithm Steps

To solve this, we will follow these steps −

  • weights := a list containing the different weights in the graph

  • connections := a list containing the union-find parent information for each weight threshold

  • Define the function query(). This will take p, q, limit

    • index := the position in weights where limit can be inserted maintaining sorted order

    • if index is 0, then return False (no edges with weight ≤ limit)

    • return True if connections[index-1][p] is same as connections[index-1][q]

Example

Let us see the following implementation to get better understanding ?

import bisect

class Solution(object):
    def __init__(self, n, edgeList):
        def find(node):
            if parent[node] != node:
                parent[node] = find(parent[node])
            return parent[node]

        def union(x, y):
            parent[find(y)] = find(x)
            return

        parent = {i: i for i in range(n)}
        edgeList.sort(key=lambda x: x[2])
        self.connections = []
        self.weights = []
        
        for index, (i, j, weight) in enumerate(edgeList):
            union(i, j)
            if index != len(edgeList) - 1 and weight == edgeList[index + 1][2]:
                continue
            self.weights.append(weight)
            self.connections.append([find(i) for i in parent])

    def query(self, p, q, limit):
        index = bisect.bisect_left(self.weights, limit)
        if index == 0:
            return False
        return self.connections[index - 1][p] == self.connections[index - 1][q]

# Create the graph and test queries
ob = Solution(5, [[0, 1, 10], [0, 2, 20], [1, 4, 10], [0, 3, 10], [1, 2, 20], [2, 3, 10]])
print(ob.query(0, 2, 10))
print(ob.query(3, 1, 30))
print(ob.query(4, 3, 30))
False
True
True

How It Works

The algorithm uses Union-Find data structure with edge sorting:

  • Preprocessing: Sort edges by weight and build snapshots of connectivity at each weight threshold

  • Query Processing: Use binary search to find the appropriate weight threshold and check if vertices are connected

  • Time Complexity: O(E log E) for preprocessing, O(log W) per query where W is number of unique weights

Conclusion

This solution efficiently answers connectivity queries with weight constraints using Union-Find and binary search. The preprocessing phase builds connectivity snapshots, enabling fast query responses in logarithmic time.

Updated on: 2026-03-26T14:46:07+05:30

236 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements