Program to check there is any common reachable node in a graph or not in Python

Suppose we have an edge list of a directed graph with n nodes numbered from 0 to n-1. Given two integer values a and b, we need to check whether there exists a node c such that we can reach both a and b from c.

0 1 2 3 4

For a = 2 and b = 3, the output will be True because node c = 0 can reach both nodes 2 and 3.

Algorithm

We'll use Depth-First Search (DFS) to find all nodes reachable from both a and b in the reversed graph ?

  1. Convert edge list to adjacency list with reversed edges
  2. Perform DFS from node a to find all nodes that can reach a
  3. Perform DFS from node b to find all nodes that can reach b
  4. Check if there's any intersection between these two sets

Implementation

def edge_list_to_graph(edges):
    # Find maximum node number to determine graph size
    nodes = set()
    for x, y in edges:
        nodes.add(x)
        nodes.add(y)
    
    graph_size = len(nodes)
    graph = [[] for _ in range(max(nodes) + 1)]
    
    # Build reversed adjacency list (y -> x instead of x -> y)
    for x, y in edges:
        graph[y].append(x)
    
    return graph

def dfs(graph, node, visited):
    if node not in visited:
        visited.add(node)
        for neighbor in graph[node]:
            dfs(graph, neighbor, visited)

def has_common_reachable_node(edges, a, b):
    # Build reversed graph
    graph = edge_list_to_graph(edges)
    
    # Find all nodes that can reach 'a' and 'b'
    reachable_to_a = set()
    reachable_to_b = set()
    
    dfs(graph, a, reachable_to_a)
    dfs(graph, b, reachable_to_b)
    
    # Check for intersection
    common_nodes = reachable_to_a.intersection(reachable_to_b)
    
    return len(common_nodes) > 0

# Example usage
edges = [(0, 4), (4, 3), (1, 2), (0, 1), (0, 2), (1, 1)]
a = 2
b = 3

result = has_common_reachable_node(edges, a, b)
print(f"Common reachable node exists: {result}")

# Show which nodes can reach both a and b
graph = edge_list_to_graph(edges)
reachable_to_a = set()
reachable_to_b = set()
dfs(graph, a, reachable_to_a)
dfs(graph, b, reachable_to_b)
common_nodes = reachable_to_a.intersection(reachable_to_b)
print(f"Common nodes: {sorted(common_nodes)}")
Common reachable node exists: True
Common nodes: [0]

How It Works

The algorithm works by reversing the graph edges. In the original graph, if there's an edge from x to y, we create an edge from y to x. This allows us to find all nodes that can reach a given target node by performing DFS from that target.

For the example above:

  • Nodes that can reach node 2: {0, 1, 2}
  • Nodes that can reach node 3: {0, 3, 4}
  • Intersection: {0}

Time and Space Complexity

Time Complexity: O(V + E) where V is the number of vertices and E is the number of edges, as we perform DFS twice.

Space Complexity: O(V + E) for storing the adjacency list and visited sets.

Conclusion

This solution efficiently finds common reachable nodes using DFS on a reversed graph. The key insight is reversing edges to find all nodes that can reach specific targets, then checking for intersections.

Updated on: 2026-03-26T16:52:18+05:30

417 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements