CODEBHAVYA โ€ข ADS LEVEL 9

๐Ÿ”— Disjoint Sets / Union-Find

Maintain non-overlapping groups, find representatives efficiently and merge components using path compression and union by rank or size.

๐ŸŽฏ Learning Objectives

After completing this level, you should be able to:

  • Explain a partition and the representative of a disjoint set.
  • Perform Make-Set, Find and Union operations.
  • Represent a collection of sets as a forest of rooted trees.
  • Apply path compression during Find.
  • Apply union by rank and union by size.
  • Use Union-Find to solve connectivity, cycle-detection and Kruskal problems.
  • Justify the nearly constant amortized complexity of optimized operations.

๐Ÿงญ 1. What Is a Disjoint-Set Structure?

A disjoint-set data structure, also called Union-Find or DSU, maintains a collection of sets that do not share elements.

Disjoint means: for any two different sets A and B, A โˆฉ B = โˆ…. Every element belongs to exactly one current set.
{0, 1, 3}{2, 5}{4}{6, 7}

One element in each set is chosen as its representative. Two elements belong to the same set exactly when their representatives are equal.

Primary Question

Are elements x and y currently in the same group?

Check Find(x) == Find(y)

Primary Update

Combine the groups containing x and y.

Perform Union(x, y)

๐ŸŒ 2. Applications of Union-Find

๐Ÿ•ธ๏ธ

Dynamic Connectivity

Track whether two network nodes are connected while links are added.

๐Ÿ”„

Cycle Detection

An edge (u, v) creates a cycle if u and v already have the same representative.

๐ŸŒ‰

Kruskalโ€™s MST

Add a light edge only when its endpoints belong to different components.

๐Ÿงฉ

Connected Components

Merge related items and count the remaining representatives.

๐Ÿ–ผ๏ธ

Image Segmentation

Combine neighbouring pixels or regions with similar properties.

๐Ÿ‘ฅ

Grouping Problems

Maintain friend circles, account groups or equivalence classes.

โš™๏ธ 3. Make-Set, Find and Union

1

Make-Set(x)

Create a new set containing only x.

parent[x] = x
2

Find(x)

Follow parent links until the root representative is reached.

parent[root] = root
3

Union(x, y)

Find both roots and attach one root below the other.

rootX โ‰  rootY
Important: Union must combine the roots, not arbitrary internal nodes. Always call Find before linking two sets.

๐ŸŒฒ 4. Forest Representation

Each set is stored as a rooted tree. All the trees together form a forest. An array named parent stores the immediate parent of every element.

Element i012345
parent[i]000244
0
1
2
3
Set {0, 1, 2, 3}
4
5
Set {4, 5}
  • A root satisfies parent[root] == root.
  • The root is used as the representative of the entire set.
  • The logical set is independent of which particular element becomes its representative.

๐Ÿ”Ž 5. Find Operation

The basic Find operation moves upward until it reaches a self-parent root.

Recursive Find Without Compression

int findSet(int x) {
    if (parent[x] == x)
        return x;
    return findSet(parent[x]);
}

Reason: every recursive call moves one level closer to the root.

Iterative Find

int findSet(int x) {
    while (parent[x] != x)
        x = parent[x];
    return x;
}

The cost depends on the tree height. A chain-shaped tree may require O(n) time.

๐Ÿ”— 6. Basic Union Operation

void unionSets(int a, int b) {
    int rootA = findSet(a);
    int rootB = findSet(b);

    if (rootA != rootB)
        parent[rootB] = rootA;
}
01

Find representative of a.

02

Find representative of b.

03

If roots differ, link one root to the other.

04

If roots match, no structural change is required.

Problem with arbitrary linking: repeatedly attaching a large tree below a small tree can create a long chain and slow down future Find operations.

๐Ÿš€ 7. Union by Rank, Union by Size and Path Compression

Union by Rank

Attach the root with smaller estimated height below the root with larger rank.

if (rank[rootA] < rank[rootB])
    parent[rootA] = rootB;

If ranks are equal, choose one root and increase only its rank.

Union by Size

Attach the smaller tree below the root of the larger tree.

if (size[rootA] < size[rootB])
    swap(rootA, rootB);
parent[rootB] = rootA;
size[rootA] += size[rootB];

Path Compression

During Find, make every visited node point directly to the root.

int findSet(int x) {
    if (parent[x] != x)
        parent[x] = findSet(parent[x]);
    return parent[x];
}
Use one union heuristic: rank and size are two alternatives. Either can be combined with path compression. Do not update rank as though it were exact height after compression.

๐Ÿงฉ 8. Worked Example

Start with elements 0 to 6. Every element is initially its own representative.

OperationResulting ComponentsReason
Union(0, 1){0, 1}, {2}, {3}, {4}, {5}, {6}Merge two singleton sets.
Union(2, 3){0, 1}, {2, 3}, {4}, {5}, {6}2 and 3 had different roots.
Union(1, 3){0, 1, 2, 3}, {4}, {5}, {6}Find(1) and Find(3) identify the two roots.
Union(4, 5){0, 1, 2, 3}, {4, 5}, {6}A third component is formed.
Find(3)Representative is 0Path compression may connect 3 directly to 0.
Representative choice: depending on tie-breaking, a different valid root may be produced. Connectivity and set membership remain the same.

๐Ÿ“ˆ 9. Complexity Analysis

ImplementationMake-SetFindUnionReason
Unoptimized forestO(1)O(n) worst caseO(n) worst caseA tree can become a chain of height nโˆ’1.
Union by rank/size onlyO(1)O(log n)O(log n)Smaller-height tree is attached below the larger one.
Path compression + rank/sizeO(1)O(ฮฑ(n)) amortizedO(ฮฑ(n)) amortizedRepeated operations flatten paths while balanced merging limits height.
ฮฑ(n) is the inverse Ackermann function. It grows so slowly that ฮฑ(n) is less than 5 for every practical input size.

Space Complexity

O(n) for parent and rank/size arrays.

Sequence of m Operations

O(m ฮฑ(n)) after O(n) initialization.

INTERACTIVE ALGORITHM VISUALIZATION

๐ŸŽฌ 10. Premium Union-Find Visualizer

CodeBhavya

Choose the number of elements and click Initialize Sets. Then perform Union, Find and connectivity queries. The structure will not run automatically when a value changes.

Click Initialize Sets to create singleton sets.

๐Ÿ’ป 11. Complete Union-Find Program

The program supports Union, Find and Connected queries using path compression and union by rank.

#include <stdio.h>

#define MAX 1000

int parent[MAX];
int rankValue[MAX];

void makeSet(int n) {
    for (int i = 0; i < n; i++) {
        parent[i] = i;
        rankValue[i] = 0;
    }
}

int findSet(int x) {
    if (parent[x] != x)
        parent[x] = findSet(parent[x]);
    return parent[x];
}

void unionSets(int a, int b) {
    int rootA = findSet(a);
    int rootB = findSet(b);

    if (rootA == rootB)
        return;

    if (rankValue[rootA] < rankValue[rootB]) {
        parent[rootA] = rootB;
    } else if (rankValue[rootA] > rankValue[rootB]) {
        parent[rootB] = rootA;
    } else {
        parent[rootB] = rootA;
        rankValue[rootA]++;
    }
}

int main(void) {
    int n, q;
    scanf("%d %d", &n, &q);

    if (n < 1 || n > MAX)
        return 0;

    makeSet(n);

    while (q--) {
        int type, a, b;
        scanf("%d", &type);

        if (type == 1) {
            scanf("%d %d", &a, &b);
            unionSets(a, b);
        } else if (type == 2) {
            scanf("%d", &a);
            printf("Representative of %d: %d\n", a, findSet(a));
        } else if (type == 3) {
            scanf("%d %d", &a, &b);
            if (findSet(a) == findSet(b))
                printf("Connected\n");
            else
                printf("Not Connected\n");
        }
    }

    return 0;
}

Sample Input

8 9
1 0 1
1 2 3
1 1 3
3 0 3
2 3
1 4 5
1 5 6
3 4 6
3 0 7

Sample Output

Connected
Representative of 3: 0
Connected
Not Connected

Time Complexity

Initialization: O(n)
Each optimized Find/Union: O(ฮฑ(n)) amortized

Space Complexity

O(n) for the parent and rank arrays, plus a very small recursive Find stack in practice.

๐Ÿ” 12. Program Tracing โ€” Union-Find Operations

Follow the sample input one operation at a time and observe how the parent and rank arrays change.

๐Ÿ”„ 13. Cycle Detection in an Undirected Graph

Process edges one by one. For an edge (u, v):

1

Find both representatives

Compute rootU = Find(u) and rootV = Find(v).

2

Same representative means a cycle

A path already connects u and v, so the new edge closes a cycle.

3

Different representatives are safe

Union the two components and continue processing.

Scope: this simple DSU method detects cycles in an undirected graph. Directed-cycle detection requires other techniques.

๐Ÿ’ก 14. Important Points and Common Mistakes

โŒ Unioning original nodes

Link roots returned by Find, not a and b directly.

โŒ Missing same-root check

If both elements already share a root, Union should make no change.

โŒ Increasing rank every time

Rank increases only when two equal-rank roots are merged.

โŒ Mixing rank and size rules

Choose one union heuristic and maintain its metadata consistently.

โŒ Forgetting path assignment

return findSet(parent[x]) finds the root but does not compress; assign the result to parent[x].

โŒ Expecting exact tree shape

Tie-breaking may create a different but equally correct forest.

  • Union-Find answers connectivity under edge additions efficiently, but basic DSU does not support deletion easily.
  • Path compression changes parent links without changing set membership.
  • Rank is an upper-bound style balancing measure, not necessarily the current exact height.
  • Counting roots after all operations gives the number of connected components.
  • Kruskalโ€™s algorithm uses DSU to reject edges that would create cycles.

โœ๏ธ 15. Practice Problems

Solve each problem first. Use Hint only when needed and Show Answer to verify your reasoning.

1. What does Make-Set(5) store initially?

2. What condition identifies a root?

3. How do we test whether a and b belong to the same set?

4. Why must Union call Find first?

5. What is the worst-case Find time in an unoptimized chain of n nodes?

6. What does path compression change?

7. In union by rank, when is a rootโ€™s rank increased?

8. In union by size, which root becomes the child?

9. Can union by rank and path compression be used together?

10. What is ฮฑ(n) in optimized DSU complexity?

11. After Union(0,1), Union(1,2), are 0 and 2 connected?

12. If Find(u) == Find(v), what happens when edge (u,v) is added to an undirected forest?

13. How many sets remain after n Make-Set operations and k successful Unions?

14. Why does Union on two already connected elements not reduce the set count?

15. What extra arrays are commonly used in optimized DSU?

16. What is the DSU space complexity for n elements?

17. Why is rank not necessarily the exact height after compression?

18. Which graph algorithm commonly uses DSU?

19. Can basic Union-Find efficiently separate a component after an edge deletion?

20. Give the amortized time for m optimized DSU operations after initialization.

๐Ÿ“ 16. Quick Revision

  • Disjoint Set Union maintains a partition of elements into non-overlapping groups.
  • Make-Set creates a singleton; Find returns a representative; Union merges two sets.
  • A parent array represents each set as a rooted tree.
  • Union by rank or size avoids unnecessarily tall trees.
  • Path compression connects visited nodes closer to the root.
  • With both optimizations, operations take O(ฮฑ(n)) amortized time.
  • DSU is central to connectivity, undirected-cycle detection and Kruskalโ€™s algorithm.