Find the number of distinct pairs of vertices which have a distance of exactly k in a tree in Python

Finding the number of distinct pairs of vertices with exactly distance k in a tree is a classic dynamic programming problem. We use DFS traversal with memoization to count paths of specific lengths from each node.

Problem Understanding

Given a tree with n nodes and an integer k, we need to count all distinct pairs of vertices that are exactly k edges apart. For the tree shown below with k = 2:

1 2 3 4 5 Pairs with distance 2: (1,3), (1,5), (3,5), (4,2)

Algorithm Approach

We use dynamic programming with DFS where vertex_count[v][d] stores the number of vertices at exactly distance d from vertex v in its subtree.

Implementation

def count_pairs_at_distance_k(edges, k, n):
    """Count pairs of vertices with exactly distance k in a tree"""
    
    # Build adjacency list
    graph = [[] for _ in range(n + 1)]
    for x, y in edges:
        graph[x].append(y)
        graph[y].append(x)
    
    # vertex_count[v][d] = number of vertices at distance d from v in its subtree
    vertex_count = [[0 for _ in range(k + 1)] for _ in range(n + 1)]
    result = 0
    
    def dfs(v, parent):
        nonlocal result
        vertex_count[v][0] = 1  # The vertex itself at distance 0
        
        for neighbor in graph[v]:
            if neighbor != parent:
                dfs(neighbor, v)
                
                # Count pairs where one vertex is in current subtree and other in neighbor's subtree
                for dist in range(1, k + 1):
                    result += vertex_count[neighbor][dist - 1] * vertex_count[v][k - dist]
                
                # Update vertex counts for current vertex
                for dist in range(1, k + 1):
                    vertex_count[v][dist] += vertex_count[neighbor][dist - 1]
    
    dfs(1, 0)
    return result

# Example usage
edges = [(1, 2), (2, 3), (3, 4), (2, 5)]
k = 2
n = 5

result = count_pairs_at_distance_k(edges, k, n)
print(f"Number of pairs with distance {k}: {result}")
Number of pairs with distance 2: 4

How It Works

The algorithm performs these key steps:

  • DFS Traversal: Visit each vertex and process its subtrees
  • Pair Counting: For each vertex, count pairs where one endpoint is in the current subtree and the other is in a child's subtree
  • Dynamic Programming: Store counts of vertices at each distance to avoid recalculation

Step-by-Step Example

def count_pairs_detailed(edges, k, n):
    graph = [[] for _ in range(n + 1)]
    for x, y in edges:
        graph[x].append(y)
        graph[y].append(x)
    
    vertex_count = [[0 for _ in range(k + 1)] for _ in range(n + 1)]
    pairs = []
    
    def dfs(v, parent, path=[]):
        vertex_count[v][0] = 1
        current_path = path + [v]
        
        print(f"Processing vertex {v}, path: {current_path}")
        
        for neighbor in graph[v]:
            if neighbor != parent:
                dfs(neighbor, v, current_path)
                
                # Find pairs at distance k
                for dist in range(1, k + 1):
                    count = vertex_count[neighbor][dist - 1] * vertex_count[v][k - dist]
                    if count > 0:
                        print(f"  Found {count} pair(s) with distance {k}")
                
                for dist in range(1, k + 1):
                    vertex_count[v][dist] += vertex_count[neighbor][dist - 1]
    
    dfs(1, 0)
    return sum(vertex_count[1])

# Run detailed example
edges = [(1, 2), (2, 3), (3, 4), (2, 5)]
count_pairs_detailed(edges, 2, 5)
Processing vertex 1, path: [1]
Processing vertex 2, path: [1, 2]
Processing vertex 3, path: [1, 2, 3]
Processing vertex 4, path: [1, 2, 3, 4]
  Found 1 pair(s) with distance 2
Processing vertex 5, path: [1, 2, 5]
  Found 2 pair(s) with distance 2
  Found 1 pair(s) with distance 2

Time Complexity

The time complexity is O(n × k) where n is the number of vertices and k is the target distance. Space complexity is O(n × k) for the memoization table.

Conclusion

This dynamic programming approach efficiently counts vertex pairs at exactly distance k using DFS traversal and memoization. The algorithm processes each vertex once and maintains distance counts for optimal performance.

Updated on: 2026-03-25T09:52:29+05:30

339 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements