The Earliest Moment When Everyone Become Friends in C++

The problem asks us to find the earliest moment when everyone in a social group becomes acquainted with everyone else. This is a classic Union-Find (Disjoint Set Union) problem where we need to track connected components and determine when all people form a single connected group.

Given N people with IDs from 0 to N-1 and a list of friendship logs, each log contains [timestamp, person_A, person_B]. We need to find the earliest timestamp when all people are connected through friendships.

Algorithm Overview

We use the Union-Find data structure with the following approach ?

  • Sort logs by timestamp to process events chronologically

  • Use Union-Find to track connected components

  • After each union operation, check if all people are in one component

  • Return the timestamp when this happens, or -1 if it never occurs

Python Implementation

Method 1: Using Union-Find with Path Compression

def earliest_acq(logs, n):
    # Initialize parent array for Union-Find
    parent = list(range(n))
    
    def find(x):
        if parent[x] != x:
            parent[x] = find(parent[x])  # Path compression
        return parent[x]
    
    def union(x, y):
        root_x = find(x)
        root_y = find(y)
        if root_x != root_y:
            parent[root_x] = root_y
            return True  # Successfully merged two components
        return False  # Already in same component
    
    # Sort logs by timestamp
    logs.sort()
    components = n  # Initially n separate components
    
    for timestamp, person_a, person_b in logs:
        if union(person_a, person_b):
            components -= 1
            if components == 1:  # All people are connected
                return timestamp
    
    return -1  # Not everyone is connected

# Test the function
logs = [[20190101,0,1],[20190104,3,4],[20190107,2,3],[20190211,1,5],
        [20190224,2,4],[20190301,0,3],[20190312,1,2],[20190322,4,5]]
n = 6

result = earliest_acq(logs, n)
print(f"Earliest moment when everyone becomes friends: {result}")
Earliest moment when everyone becomes friends: 20190301

Step-by-Step Execution

Let's trace through the example to understand how the algorithm works ?

def earliest_acq_with_trace(logs, n):
    parent = list(range(n))
    
    def find(x):
        if parent[x] != x:
            parent[x] = find(parent[x])
        return parent[x]
    
    def union(x, y):
        root_x = find(x)
        root_y = find(y)
        if root_x != root_y:
            parent[root_x] = root_y
            return True
        return False
    
    def get_components():
        groups = {}
        for i in range(n):
            root = find(i)
            if root not in groups:
                groups[root] = []
            groups[root].append(i)
        return list(groups.values())
    
    logs.sort()
    components = n
    
    print(f"Initial components: {get_components()}")
    
    for timestamp, person_a, person_b in logs:
        if union(person_a, person_b):
            components -= 1
            print(f"Timestamp {timestamp}: Connected {person_a} and {person_b}")
            print(f"Current components: {get_components()}")
            if components == 1:
                return timestamp
        else:
            print(f"Timestamp {timestamp}: {person_a} and {person_b} already connected")
    
    return -1

# Test with trace
logs = [[20190101,0,1],[20190104,3,4],[20190107,2,3],[20190211,1,5],
        [20190224,2,4],[20190301,0,3],[20190312,1,2],[20190322,4,5]]
n = 6

result = earliest_acq_with_trace(logs, n)
print(f"\nFinal result: {result}")
Initial components: [[0], [1], [2], [3], [4], [5]]
Timestamp 20190101: Connected 0 and 1
Current components: [[2], [3], [4], [5], [0, 1]]
Timestamp 20190104: Connected 3 and 4
Current components: [[2], [5], [0, 1], [3, 4]]
Timestamp 20190107: Connected 2 and 3
Current components: [[5], [0, 1], [2, 3, 4]]
Timestamp 20190211: Connected 1 and 5
Current components: [[0, 1, 5], [2, 3, 4]]
Timestamp 20190224: 2 and 4 already connected
Timestamp 20190301: Connected 0 and 3
Current components: [[0, 1, 5, 2, 3, 4]]

Final result: 20190301

Time and Space Complexity

Aspect Complexity Explanation
Time O(M log M + M ?(N)) M logs sorting + M union operations
Space O(N) Parent array for Union-Find

Where M is the number of logs, N is the number of people, and ? is the inverse Ackermann function (practically constant).

Key Points

  • Path Compression: Optimizes find operations by flattening the tree structure

  • Component Counting: Track the number of separate components to detect when all are connected

  • Early Termination: Return immediately when components count reaches 1

  • Sorting: Process events chronologically to find the earliest moment

Conclusion

The Union-Find data structure efficiently solves this connectivity problem by tracking connected components and detecting when all people form a single group. The algorithm processes friendship events chronologically and returns the earliest timestamp when everyone becomes acquainted.

---
Updated on: 2026-03-25T08:20:08+05:30

192 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements