Union-Find (Disjoint Set Union)
Union-Find (còn gọi DSU — Disjoint Set Union, tập rời nhau) trả lời cực nhanh hai câu hỏi: "hai phần tử có cùng nhóm không?" và "gộp hai nhóm lại". Với hai tối ưu nén đường (path compression) và hợp theo hạng (union by rank), mỗi thao tác gần như O(1) khấu hao. Đây là cấu trúc đứng sau Kruskal.
1. Trực quan: ai cùng băng nhóm?
Hình dung một sân chơi đông trẻ, dần dần kết bạn thành các nhóm. Bạn cần biết nhanh: "hai bạn này cùng nhóm chưa?" và "nhập hai nhóm lại làm một". Mỗi nhóm chọn một bạn làm trưởng nhóm (đại diện). Hỏi "cùng nhóm?" = "hai bạn có cùng trưởng nhóm không?".
Moi nhom la mot cay, goc = dai dien:
1 4
/ \ |
2 3 5
nhom A = {1,2,3} (dai dien 1)
nhom B = {4,5} (dai dien 4)
find(3) leo len goc -> 1
find(5) -> 4 => 3 va 5 KHAC nhom
2. Hai thao tác cốt lõi
| Thao tác | Ý nghĩa |
|---|---|
| find(x) | tìm đại diện (gốc) của nhóm chứa x |
| union(a, b) | gộp nhóm của a và nhóm của b |
Cài đặt cơ bản: mảng parent, ban đầu mỗi phần tử là cha của chính nó (mỗi người một nhóm riêng).
find leo theo parent tới khi gặp gốc (phần tử có parent[x] == x).
3. Chạy debug: union rồi find
4. Code chạy được (đầy đủ tối ưu)
5. Hai tối ưu làm nên tốc độ
Nén đường (path compression): mỗi lần find, kéo các node trên đường về sát gốc, làm cây phẳng
dần — lần hỏi sau nhanh hơn.
Hợp theo hạng (union by rank): khi gộp, luôn treo cây thấp vào cây cao để cây không bị
dài ra. Kết hợp cả hai, mỗi thao tác chỉ tốn O(α(n)) — với α là hàm Ackermann ngược, gần như là
hằng số (≤ 4 với mọi n thực tế).
Truoc nen: Sau khi find(4):
1 1
| / | \
2 2 3 4
|
3
|
4
6. Phân tích & ứng dụng
| Thao tác | Độ phức tạp (có 2 tối ưu) |
|---|---|
| find | gần O(1) khấu hao — O(α(n)) |
| union | gần O(1) khấu hao |
Ứng dụng:
- Kruskal: kiểm tra cạnh có tạo chu trình không.
- Đếm số thành phần liên thông khi thêm cạnh dần.
- Kiểm tra hai phần tử "cùng nhóm" trong các bài gom cụm, mạng xã hội.
Bẫy thường gặp: quên một trong hai tối ưu → cây có thể suy biến thành chuỗi dài, find tụt về O(n).
7. Mẫu nhận diện
- "Gộp nhóm", "cùng một tập / cùng kết nối?", "thành phần liên thông động" → Union-Find.
- "Thêm cạnh dần và hỏi số cụm" → DSU cập nhật nhanh hơn chạy lại DFS mỗi lần.
- Là bước phụ trong Kruskal và nhiều bài đồ thị offline.
8. 🎮 Trò chơi: Hiểu Union-Find
9. Quiz kiểm tra nhanh
10. Hoàn thành
…☑️ Tiếp theo: 3.4.1 — Quy hoạch động: DP là gì (nhớ lại kết quả con để giải bài lớn).