Program to check existence of edge length limited paths in Python

Given an undirected weighted graph with n nodes and an edgeList where each edge is represented as (u, v, w) indicating a path from node u to node v with distance w. We also have queries in the format (p, q, lim) asking whether there exists a path from node p to node q with total distance less than lim.

This problem can be efficiently solved using the Union-Find (Disjoint Set Union) data structure combined with sorting techniques.

Algorithm Overview

The approach involves:

  • Sort edges by weight in ascending order
  • Sort queries by their limit value
  • For each query, progressively add edges with weight less than the limit
  • Use Union-Find to check if two nodes are connected

Implementation

def solve(n, edgeList, queries):
    # Initialize Union-Find structure
    parent = [i for i in range(n + 1)]
    rank = [0 for i in range(n + 1)]
    
    def find(parent, x):
        if parent[x] == x:
            return x
        parent[x] = find(parent, parent[x])  # Path compression
        return parent[x]
    
    def union(parent, a, b):
        root_a = find(parent, a)
        root_b = find(parent, b)
        
        if root_a == root_b:
            return
        
        # Union by rank
        if rank[root_a] < rank[root_b]:
            parent[root_a] = root_b
        elif rank[root_a] > rank[root_b]:
            parent[root_b] = root_a
        else:
            parent[root_b] = root_a
            rank[root_a] += 1
    
    # Sort edges by weight
    edgeList.sort(key=lambda x: x[2])
    
    # Prepare result array and sort queries by limit
    result = [False] * len(queries)
    indexed_queries = [[i, query] for i, query in enumerate(queries)]
    indexed_queries.sort(key=lambda x: x[1][2])
    
    edge_index = 0
    
    for query_idx, (p, q, limit) in indexed_queries:
        # Add all edges with weight < limit
        while edge_index < len(edgeList) and edgeList[edge_index][2] < limit:
            u, v, weight = edgeList[edge_index]
            union(parent, u, v)
            edge_index += 1
        
        # Check if p and q are connected
        result[query_idx] = find(parent, p) == find(parent, q)
    
    return result

# Test the function
n = 4
edgeList = [(1, 2, 16), (1, 3, 8), (2, 4, 3), (2, 3, 6), (4, 3, 3)]
queries = [(1, 4, 12), (2, 3, 3), (1, 2, 15)]

print(solve(n, edgeList, queries))
[True, False, True]

How It Works

Let's trace through the example:

Sorted edges by weight: [(2,4,3), (4,3,3), (2,3,6), (1,3,8), (1,2,16)]

Sorted queries by limit: [(2,3,3), (1,4,12), (1,2,15)]

  • Query (2,3,3): No edges with weight < 3, so nodes 2 and 3 are not connected ? False
  • Query (1,4,12): Add edges with weight < 12: (2,4,3), (4,3,3), (2,3,6), (1,3,8). Path 1?3?4 exists ? True
  • Query (1,2,15): All previous edges remain, path 1?3?2 exists ? True

Time Complexity

Operation Time Complexity
Sorting edges O(E log E)
Sorting queries O(Q log Q)
Union-Find operations O((E + Q) ?(n))
Total O(E log E + Q log Q)

Where E is the number of edges, Q is the number of queries, and ? is the inverse Ackermann function.

Conclusion

This solution efficiently handles multiple path existence queries by combining Union-Find with sorting. The key insight is processing queries in order of increasing limits to avoid redundant edge processing.

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

222 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements