DisjointSet-unionFind
Disjoint Set
๋ฒ์ญํ๋ฉด ์๋ก์ ์งํฉ
์ผ๋ก ์๋ก ์ค๋ณต ๋์ง ์๋ ๋ถ๋ถ ์งํฉ๋ค๋ก ์ด๋ฃจ์ด์ง ์งํฉ(set).
ํ๋ง๋๋ก ๊ต์งํฉ์ด ์กด์ฌ ํ์ง ์๋ ๋ถ๋ถ์งํฉ๋ค๋ก ์ด๋ฃจ์ด์ง ์งํฉ.
Union-Find
Union
: ๋๊ฐ์ ์งํฉ์ ํ๋์ ์งํฉ์ผ๋ก ํฉ์น๋ ๊ฒ.
Find
: ์ด๋ค ์์๊ฐ ์ฃผ์ด์ก์ ๋ ์ด ์์๊ฐ ์ํ ์งํฉ์ ๋ฐํํ๋(์ฐพ๋) ๊ฒ.
์งํฉ๋ค์ tree
๊ตฌ์กฐ๋ก ๋ํ๋ด์ด ํด๋น์์๊ฐ ์ด๋ค ์งํฉ์ ์ํ๋์ง ํ๋จํ ๋ ๊ฐ ์งํฉ์ ๋ํ๊ฐ(root)์ ์ด์ฉํด์ ์งํฉ์ด ๊ฐ์์ง๋ฅผ ๋น๊ต.
๊ตฌํ ๋ฐฉ๋ฒ
์ฐ๊ฒฐ๋ฆฌ์คํธ
typedef struct node{
int data;
struct node* parent;
struct node* next;
}node;
void MakeSet(node* p,int x){
p->data = x;
p->parent = p;//์ฒ์์ ๋ค ์์๊ฐ ํ๋์ฉ์๋ ์งํฉ์ด๋ฏ๋ก ์๊ธฐ ์์ ์ด root
p->next=null;
}
void Find(node* p,int x){
if(p->parent->data == x) return x; //root๊ฐ์ด ์๊ธฐ ์์ ์ด๋ผ๋ฉด ์งํฉ์ ๋ํ๊ฐ
else return Find(p->parent,x); //์ฌ๊ท์ ์ผ๋ก ์งํฉ ๋ํ๊ฐ ์ฐพ๊ธฐ
}
void Union(node* p1,node* p2,int x,int y){
x = Find(p1,x);
y = Find(p2,y);
p1->next = p2;
p2->parent = p1;
}
Disjoint Set Forest ( Tree )
int root[n];
void MakeSet(int x){
root[x] = x; //์ฒ์์ ๋ค ์์๊ฐ ํ๋์ฉ์๋ ์งํฉ์ด๋ฏ๋ก ์๊ธฐ ์์ ์ด root
}
void Find(int x){
if(root[x] == x) return x; //root๊ฐ์ด ์๊ธฐ ์์ ์ด๋ผ๋ฉด ์งํฉ์ ๋ํ๊ฐ
else return Find(root[x]); //์ฌ๊ท์ ์ผ๋ก ์งํฉ ๋ํ๊ฐ ์ฐพ๊ธฐ
}
void Union(int x,int y){
x = Find(x);
y = Find(y);
root[y] = x;
}
์๊ฐ ๋ณต์ก๋
์ฐ๊ฒฐ๋ฆฌ์คํธ
๋ก ๊ตฌํ์ O(nlgn)
์ ์๊ฐ์ ๊ฐ์ผ๋ฉฐ Tree
๋ก ๊ตฌํํด๋ ๋ถ๊ท ํํ ํธ๋ฆฌ (์ : skewd tree)์ ๊ฐ๊ฒ ๋๋ฉด ์ฐ๊ฒฐ๋ฆฌ์คํธ์ ๋ค๋ฅผ ๊ฒ์ด ์์ด์ง๋ค.
๋ฌธ์ ์
find์์ ์ฌ๊ท์ ์ผ๋ก ์ฐพ๊ธฐ ๋๋ฌธ์ ๋ง์ฝ์ set์ tree๊ตฌ์กฐ๊ฐ ์ ํ์ ์ธ ํํ๋ผ๊ณ ํ๋ค๋ฉด ์ต์ ์ ๊ฒฝ์ฐ๋ก O(n)๋งํผ์ ์๊ฐ์ด ์์ ๋๊ฒ ๋๋ค.
โก path compression (๊ฒฝ๋ก ์์ถ)
๊ธฐ๋ฒ ์ฌ์ฉ
๋ํ, union์์ ๊น์ด๊ฐ ์์ ํธ๋ฆฌ์ ๊น์ด๊ฐ ๊น์ ํธ๋ฆฌ๋ฅผ ๋ถ์ด๊ฒ ๋๋ฉด ๊น์ด๊ฐ ๋ ์ฆ๊ฐํ์ฌ ์๊ฐ์ ์ ์ํฅ์ ์ค๋ค.
โก union by rank
๊ธฐ๋ฒ ์ฌ์ฉ
path compression (๊ฒฝ๋ก ์์ถ)
find ์ฐ์ฐ ์ํ์๋ง๋ค ํธ๋ฆฌ์ ๊ตฌ์กฐ๋ฅผ ํํํ๊ฒ ๋ง๋๋ ๋ฐฉ๋ฒ.
๊ฐ root๊ฐ์ ์ฌ๊ท์ ์ผ๋ก ๊ฐ๋ฆฌํค๋ ๊ฒ์ด ์๋ ํด๋น ์งํฉ์ ์ํ๋ ์์๋ ๋ชจ๋ ๋์ผํ root
๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋ง๋๋ ๋ฐฉ๋ฒ
void Find(int x){
/*find์ํ๋ง๋ค ํด๋น parent๊ฐ์ root๋ก ์ด๊ธฐํ*/
if(root[x] != x) root[x] = Find(root[x]);
else return root[x];
}
union by rank
ํญ์ ๊น์ด๊ฐ ๊น์ ํธ๋ฆฌ์ ์์ ํธ๋ฆฌ๋ฅผ ๋ถ์ฌ ๊น์ด๋ฅผ ์ ์งํ๋ ๋ฐฉ๋ฒ.
๊น์ด๊ฐ ์๋ก ๊ฐ์ ํธ๋ฆฌ๋ผ๋ฉด, ๊น์ด๋ฅผ 1์ฆ๊ฐ ์ํจ๋ค.
int root[n];
int rank[n];
void MakeSet(int x){
root[x] = x; //์ฒ์์ ๋ค ์์๊ฐ ํ๋์ฉ์๋ ์งํฉ์ด๋ฏ๋ก ์๊ธฐ ์์ ์ด root
rank[x] = 0; //๊น์ด๋ 0์ผ๋ก ์ด๊ธฐํ
}
void Union(int x,int y){
x = Find(x); //์
๋ ฅ๋ฐ์ x๊ฐ์ root๊ฐ์ ์ ์ฅ
y = Find(y); //์
๋ ฅ๋ฐ์ y๊ฐ์ root๊ฐ์ ์ ์ฅ
if(x==y) return; //root๊ฐ ๊ฐ๋ค๋ฉด ๊ฐ์ ์งํฉ
if(rank[x] < rank[y]) root[x] = y; //x์ root๋ฅผ y๋ก ๋ณ๊ฒฝ
else if(rank[x] > rank[y]) root[y]= x; //y์ root๋ฅผ x๋ก ๋ณ๊ฒฝ
else{
root[y] = x;
rank[x]++; //๊น์ด๊ฐ ๊ฐ๋ค๋ฉด x์ y๋ฅผ ๋ถ์์ผ๋ฏ๋ก x๊น์ด ์ฆ๊ฐ
}
๋ ๊ธฐ๋ฒ์ ์ ์ฉ ํ ์๊ฐ ๋ณต์ก๋
O(lgn)
ํ์ฉ
Disjoint Set ์๋ฃ๊ตฌ์กฐ
๋ ์งํฉ์ ๋ถํ ์ ๋ชจ๋ธ๋ง ํ๊ธฐ ๋๋ฌธ์ ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ(undirected graph)
์ ์ฐ๊ฒฐ๋ ์์๋ค์ ์ถ์
ํ ์ ์์ด, ์ฌ์ดํด์ด ๋ฐ์ํ๋์ง / ๊ฐ์ ์์์ ์ํ๋์ง ํ์ธ ํ ์ ์๋ค.
๋ํ์ ์ผ๋ก MST
๋ฅผ ์ฐพ๋ Kruskal ์๊ณ ๋ฆฌ์ฆ
์ ์ด์ฉ๋๋ค.
Last updated