Union-Find (ํ•ฉ์ง‘ํ•ฉ ์ฐพ๊ธฐ)

Union-Find๋Š” ๊ทธ๋ž˜ํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ํ•ฉ์ง‘ํ•ฉ ์ฐพ๊ธฐ ๋˜๋Š” ์„œ๋กœ์†Œ ์ง‘ํ•ฉ(Disjoint-Set) ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ผ๊ณ  ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค.

๊ฐ™์€ ๊ทธ๋ž˜ํ”„ ๋‚ด์— ํ™•์ธํ•˜๊ณ  ์‹ถ์€ ๋…ธ๋“œ๋“ค์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. 

 

Union-Find๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฐฐ์—ด์ด ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฒ˜์Œ์—๋Š” ๋ชจ๋“  ๊ฐ’์ด ์ž๊ธฐ ์ž์‹ ์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๋งŒ๋“ญ๋‹ˆ๋‹ค. 

ํ‘œ์™€ ๊ทธ๋ฆผ์œผ๋กœ ๊ทธ๋ฆฌ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋…ธ๋“œ 1 2 3 4 5 6 7 8
๋…ธ๋“œ์˜ ๋ถ€๋ชจ 1 2 3 4 5 6 7 8

 

์ดํ›„ 2๊ฐœ์˜ ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ ์ค‘ ๋” ์ž‘์€ ๊ฐ’์œผ๋กœ ๋ถ€๋ชจ ๋…ธ๋“œ ๋ฐฐ์—ด ๊ฐ’์„ ๋ฐ”๊ฟ”์ค๋‹ˆ๋‹ค.

๋งŒ์•ฝ 1๊ณผ 2๊ฐ€ ์—ฐ๊ฒฐ๋˜์—ˆ๋‹ค๊ณ  ํ•˜๋ฉด 2์˜ ๋ถ€๋ชจ ๋…ธ๋“œ ์•„๋ž˜์™€ ๊ฐ™์ด 1๋กœ ๋ฐ”๋€๋‹ˆ๋‹ค.

๋ถ€๋ชจ์˜ ๊ฐ’์ด ๊ฐ™์•„์ง์œผ๋กœ์จ ๋…ธ๋“œ๋“ค์„ ํ•ฉ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (Union ์•Œ๊ณ ๋ฆฌ์ฆ˜)

๋…ธ๋“œ 1 2 3 4 5 6 7 8
๋…ธ๋“œ์˜ ๋ถ€๋ชจ 1 1 3 4 5 6 7 8

์ดํ›„ 2์™€ 3๋„ ์—ฐ๊ฒฐํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฉ๋‹ˆ๋‹ค.

๋…ธ๋“œ 1 2 3 4 5 6 7 8
๋…ธ๋“œ์˜ ๋ถ€๋ชจ 1 1 2 4 5 6 7 8

์ตœ์ข…์ ์œผ๋กœ 1, 2, 3 ๋ชจ๋‘ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”๋ฐ 1๊ณผ 3์˜ ๋ถ€๋ชจ ๋…ธ๋“œ๋Š” ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์žฌ๊ท€ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋“œ์™€ ๋…ธ๋“œ์˜ ๋ถ€๋ชจ ๊ฐ’์ด ๊ฐ™์„ ๋•Œ๊นŒ์ง€ ์—ฐ๊ฒฐ ํ™•์ธ์„ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.

 

Find ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‘ ๊ฐœ์˜ ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ํ™•์ธํ•˜์—ฌ ํ˜„์žฌ ๊ฐ™์€ ์ง‘ํ•ฉ์— ์†ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.

 

์•„๋ž˜๋Š” Union-Find ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ธฐ๋ณธ ๊ตฌํ˜„ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. 

#include <stdio.h>

// ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š” ํ•จ์ˆ˜
int getParent(int parent[], int x) {
  if(parent[x] == x) return x;
  return parent[x] = getParent(parent, parent[x]);
}

// ๋‘ ๋ถ€๋ชจ ๋…ธ๋“œ๋ฅผ ํ•ฉ์น˜๋Š” ํ•จ์ˆ˜
int unionParent(int parent[], int a, int b) {
  a = getParent(parent, a);
  b = getParent(parent, b);
  if(a < b) parent[b] = a;
  else parent[a] = b;
}

// ๊ฐ™์€ ๋ถ€๋ชจ๋ฅผ ๊ฐ€์ง€๋Š”์ง€ ํ™•์ธ
int findParent(int parent[], int a, int b) {
  a = getParent(parent, a);
  b = getParent(parent, b);
  if(a == b) return 1;
  return 0;
}

int main(void) {
  int parent[11];
  for(int i = 0; i <= 10; i++) {
    parent[i] = i;
  }
  unionParent(parent, 1, 2);
  unionParent(parent, 2, 3);
  unionParent(parent, 3, 4);
  unionParent(parent, 5, 6);
  unionParent(parent, 6, 7);
  unionParent(parent, 7, 8);
  printf("1๊ณผ 5๋Š” ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‚˜์š”? %d\n", findParent(parent, 1, 5));
  unionParent(parent, 2, 8);
  printf("1๊ณผ 5๋Š” ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‚˜์š”? %d\n", findParent(parent, 1, 5));
}

 

 

 

 

 

 

 

Reference

https://blog.naver.com/ndb796/221230967614

 

17. Union-Find(ํ•ฉ์ง‘ํ•ฉ ์ฐพ๊ธฐ)

Union-Find(์œ ๋‹ˆ์˜จ-ํŒŒ์ธ๋“œ)๋Š” ๋Œ€ํ‘œ์ ์ธ ๊ทธ๋ž˜ํ”„ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. ๋ฐ”๋กœ 'ํ•ฉ์ง‘ํ•ฉ ์ฐพ๊ธฐ'๋ผ๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„ ์•Œ...

blog.naver.com