Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

1/Tổng quan về DSU

Disjoint Sets Union (gọi tắt là DSU) là một cấu trúc dữ liệu chứa nhiều phần tử được phân
chia vào các tập hợp khác nhau. DSU có thể gộp hai tập hợp cũng như cho biết một phần
tử thuộc tập hợp nào.

Một DSU sẽ hỗ trợ các phương thức cơ bản sau:

 Tạo tập hợp chứa các phần tử

 Gộp hai tập hợp chứa hai phần tử yêu cầu lại làm một
 Tìm kiếm tập hợp chứa phần tử yêu cầu

2/ Xây dựng DSU


Thông thường, DSU sẽ được xây dựng dưới dạng một đồ thị có hướng như mình đã trình
bày ở phần trên. Để thể hiện cạnh có hướng nối từ đỉnh này đến đỉnh khác, ta sẽ dùng một
mảng parent với ý nghĩa parent[u] = v là tồn tại cạnh có hướng nối từ đỉnh u đến đỉnh v.

Để khởi tạo tập hợp chứa các phần tử, ta đơn giản chỉ cần tạo ra một cây có đỉnh là chính
phần tử đó.

Để có thể gộp hai tập hợp chứa hai phần tử yêu cầu lại làm một, trước hết ta sẽ phải tìm
xem đỉnh gốc của hai tập hợp chứa hai phần tử của hai phần tử đã cho rồi sau đó, gán cha
của một đỉnh là đỉnh còn lại.

Để tìm tập hợp chứa phần tử yêu cầu, ta chỉ cần đi theo cha của đỉnh đó tới khi đến đỉnh
gốc (đỉnh có cha là chính nó)

Xét bài toán:


#include<bits/stdc++.h>
using namespace std;

const int MaxN = 1 + 1e6;

int n, q, parent[MaxN];

void make_set(int u){


parent[u] = u;
}

int find_set(int u){


if(u == parent[u]) return u;
return parent[u] = find_set(parent[u]);
}

void union_set(int u, int v){


u = find_set(u);
v = find_set(v);
if(u == v) return;
parent[u] = v;
}

int main(){
cin >> n >> q;
for(int i = 1 ; i <= n ; ++i) make_set(i);
while(q--){
char query;
int x, y;
cin >> query >> x >> y;
if(query == 'Q'){
if(find_set(x) == find_set(y)) cout << "YES" << endl;
else cout << "NO" << endl;
}
else{
union_set(x, y);
}
}

return 0;
}
//6 8
//U 2 3
//U 3 5
//Q 5 2
//U 1 4
//Q 1 2
//U 1 3
//U 2 4
//Q 2 1

You might also like