λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
  • μž₯원읡 κΈ°μˆ λΈ”λ‘œκ·Έ
πŸ’» Computer Science/- Data Structure, Algorithm

[μ•Œκ³ λ¦¬μ¦˜-이둠] 09 μ§‘ν•©μ˜ 처리

by Wonit 2019. 11. 23.

μ§‘ν•©μ˜ 처리

 

μƒν˜Έ 배타적인 μ—¬λŸ¬ 개의 집합을 μ²˜λ¦¬ν•΄μ•Ό ν•  κ²½μš°κ°€ μžˆλŠ”λ° μ΅œμ†Œ μ‹ μž₯ 트리λ₯Ό μœ„ν•œ 크루슀칼 μ•Œκ³ λ¦¬μ¦˜μ—μ„œ μƒν˜Έ 배타적인 집합을 μ²˜λ¦¬ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ΄ ν•„μš”ν•˜λ‹€.

 

μ§‘ν•©μ˜ κ΄€λ¦¬μ—μ„œ ν•„μš”ν•œ 연산은 μž„μ˜μ˜ μ›μ†Œκ°€ μ–΄λŠ 집합에 μ†ν•˜λŠ”μ§€ μ•Œλ‚˜λ‚΄λŠ” μ—°μ‚°κ³Ό 두 집합을 ν•©ν•˜λŠ” 연산이닀.

 

μ—¬κΈ°μ„œ 말 ν•˜λŠ” μƒν˜Έ 배타적인 집합은 μ„œλ‘œμ˜ ꡐ집합이 곡집합인 경우λ₯Ό λœ»ν•œλ‹€.

μ—°κ²° 리슀트λ₯Ό μ΄μš©ν•œ μ§‘ν•©μ˜ 처리

 

μ—°κ²° 리슀트λ₯Ό μ΄μš©ν•œ ν‘œν˜„μ€ 쉽고 직관적이닀. ++각 μ›μ†Œλ‹Ή ν•˜λ‚˜μ˜ λ…Έλ“œλ₯Ό λ§Œλ“€κ³  이듀을 μ—°κ²°λ¦¬μŠ€νŠΈλ‘œ μ—°κ²°ν•œλ‹€++

λ…Έλ“œλŠ” 두 개의 포인터와 μ›μ†Œλ₯Ό κ°–λŠ” ν•œ 개의 ν•„λ“œλ‘œ 이루어 진닀.

λ‹€μŒ μ›μ†Œ 포인터 -> λ‹€μŒ μ›μ†Œλ₯Ό κ°€λ¦¬ν‚€λŠ” 포인터. 각 μ§‘ν•©μ—λŠ” λ§ˆμ§€λ§‰ μ›μ†Œλ₯Ό κ°€λ¦¬ν‚€λŠ” tailμ΄λΌλŠ” λ³€μˆ˜λ₯Ό λ‘”λ‹€.
λŒ€ν‘œ μ›μ†Œ 포인터 -> μ—°κ²° 리슀트의 맨 μ•žμ— μžˆλŠ” μ›μ†Œ.

μ—°κ²°λ¦¬μŠ€νŠΈ λ…Έλ“œ

)

μƒν˜Έ 배타적 μ§‘ν•©μ˜ 관리λ₯Ό μœ„ν•΄ ν•„μš”ν•œ ++μ„Έ 가지 μ—°μ‚°++

Make-Set(x)

  • μ›μ†Œ x둜만 κ΅¬μ„±λœ 집합을 λ§Œλ“ λ‹€.

Find-Set(x)

  • μ›μ†Œ xλ₯Ό 가진 집합을 μ•Œμ•„λ‚Έλ‹€.

Union(x, y)

  • μ›μ†Œ xλ₯Ό 가진 집합과 μ›μ†Œ yλ₯Ό 가진 집합을 ν•˜λ‚˜μ˜ μ§‘ν•©μœΌλ‘œ ν•©μΉœλ‹€.

μž‘μ—…μ˜ κ°œμš”

μ‹€μ œμ μœΌλ‘œ 연산을 ν•΄λ³΄μž.

μ—°κ²°λ¦¬μŠ€νŠΈ 집합 a

μ—°κ²° 리슀트 집합 a와 a = {a,b,c}

μ—°κ²°λ¦¬μŠ€νŠΈ 집합 b

μ—°κ²° 리슀트 집합 bλ₯Ό ν•©μΉœλ‹€κ³  ν•˜μž! b = {d,e,f,g,h}
  1. Union(a, b);

    Union이 이루어진닀면. λŒ€ν‘œ μ›μ†Œλ₯Ό λ°”κΏ”μ„œ 이어쀀닀.

1μ—°κ²°λ¦¬μŠ€νŠΈ union

μ΄λ ‡κ²Œ ν–‰λ ¬ a = {a,b,c}의 λŒ€ν‘œ μ›μ†Œλ₯Ό aκ°€ μ•„λ‹Œ d둜 연결을 μ‹œμΌœμ€€λ‹€.

무게λ₯Ό κ³ λ €ν•œ Union^Weighted_Union^

μ—°κ²° 리슀트 ν‘œν˜„μ—μ„œ Make-Set은 ν•˜λ‚˜μ˜ μ›μ†Œλ‘œ 된 집합을 μ΄ˆκΈ°ν™”ν•˜λŠ” κ²ƒμ΄λ―€λ‘œ μƒμˆ˜ μ‹œκ°„μ΄ λ“ λ‹€. λ˜ν•œ Find-Set도 μƒμˆ˜ μ‹œκ°„μ΄ λ“œλŠ”λ°, 이 쀑 μƒμˆ˜ μ‹œκ°„μ„ μ΄ˆκ³Όν•˜λŠ” 것은 Union 뿐이닀.

크기가 λ‹€λ₯Έ 두 집합이 μžˆλ‹€κ³  ν•˜μž.

A = {1, 3, 5}

B = {2, 4, 6, 8, 10}

Union(A, B)λ₯Ό ν–ˆμ„ λ•Œ λŒ€ν‘œ μ›μ†Œλ₯Ό λŠλŠ” κ²½μš°λŠ” 두 가지가 μžˆλ‹€.

  1. A의 λŒ€ν‘œ μ›μ†Œλ₯Ό λ°”κΎΈλŠ” 경우.
  2. B의 λŒ€ν‘œ μ›μ†Œλ₯Ό λ°”κΎΈλŠ” 경우.

1번 같은 κ²½μš°λŠ” 1, 3, 5의 μ›€μ§μž„ (3번) , 2번 같은 κ²½μš°λŠ” 2, 4, 6, 8, 10의 μ›€μ§μž„ (5번)의 차이가 μžˆλ‹€.

이런 λ°©μ‹μœΌλ‘œ 두 집합을 ν•©μΉ˜λŠ” 것을 무게λ₯Ό κ³ λ €ν•œ Union이라고 ν•œλ‹€.

μˆ˜ν–‰ μ‹œκ°„.

μ—°κ²° 리슀트λ₯Ό μ΄μš©ν•΄ ν‘œν˜„λ˜λŠ” 배타적 μ§‘ν•©μ—μ„œ 무게λ₯Ό κ³ λ €ν•œ Union을 μ‚¬μš©ν•  λ•Œ, M번의 Make-Set, Union, Find-Set쀑 n번이 Make-Set이라면 μ΄λ“€μ˜ 총 μˆ˜ν–‰ μ‹œκ°„μ€?
  • n번의 Make-Set을 ν¬ν•¨ν•˜λ―€λ‘œ μ›μ†Œμ˜ 총 μˆ˜λŠ” nκ°œλ‹€.

  • Make-Setκ³Ό Find-Set은 각각 O(1)의 μ‹œκ°„μ΄ λ“€κ³  이듀을 합해도 mλ²ˆμ„ λ„˜μ§€ μ•ŠμœΌλ―€λ‘œ μ΄λ“€λ‘œ μΈν•œ 뢀담은 O(m)이닀.

  • κ²°κ΅­ λ¬Έμ œλŠ” Union이고, Unionμ—μ„œ μ‹œκ°„μ„ κ²°μ •ν•˜λŠ” 것은 λŒ€ν‘œ λ…Έλ“œλ‘œ 포인터λ₯Ό κ°±μ‹ ν•˜λŠ” μž‘μ—…μ΄λ‹€.

    Unionμ—μ„œ 집합에 xλΌλŠ” 값이 μžˆλ‹€κ³  ν•˜μž, 이 x값은 λ˜ν•œ Unionν•¨μˆ˜μ— μ˜ν•΄μ„œ λ§Œλ“€μ–΄ μ‘ŒμœΌλ―€λ‘œ 식은
    Union(n/2, n/2)이 λœλ‹€. λ˜ν•œ n/2도 Union(n/4, n/4)둜 이루어 μ Έ 점점 1 -> 2^2^ -> 2^3^ -> 2^4^ 의 λΉ„μœ¨λ‘œ 컀진닀.
    ν•˜μ§€λ§Œ μ›μ†Œμ˜ 총 μˆ˜λŠ” nμ΄λ―€λ‘œ λͺ¨λ“  μ›μ†Œλ₯Ό κ³ λ €ν•œλ‹€λ©΄ 기껏해야 nLog(2^n^)을 λ„˜μ§€ μ•ŠλŠ”λ‹€. κ·ΈλŸ¬λ―€λ‘œ 전체 μ‹œκ°„μ€

O(m+nlogn) 이닀.

트리λ₯Ό μ΄μš©ν•œ μ§‘ν•©μ˜ 처리

μ—°κ²° 리슀트λ₯Ό μ΄μš©ν•œ Union μ—μ„œλŠ” κ²°κ΅­ 두 번의 포인터 갱신이 ν•„μš”ν•œλ° 이 λ§ˆμ €λ„ 효율적으둜 ν•  수 있게 ν•΄μ£ΌλŠ” 것이 λ°”λ‘œ 트리λ₯Ό μ΄μš©ν•œ μ§‘ν•©μ˜ μ²˜λ¦¬μ΄λ‹€.

κΈ°λ³Έ 원리

트리λ₯Ό μ΄μš©ν•œλ‹€λ©΄ μ—°κ²° λ¦¬μŠ€νŠΈμ—μ„œμ˜ 것 처럼 두 번의 갱신이 ν•„μš”ν•˜μ§€ μ•Šκ³  단지 루트 λ…Έλ“œμ˜ μœ„μΉ˜λ§Œ λ°”κΏ”μ€€λ‹€λ©΄ ν•œ λ²ˆμ— Union이 κ°€λŠ₯ν•˜λ‹€.

트리λ₯Ό μ΄μš©ν•˜λ €λ©΄ 두 κ°€μ§€μ˜ νŠΉμ§•μ„ μ•Œμ•„μ•Ό ν•œλ‹€.

트리의 두 가지 νŠΉμ§•

  • μžμ‹ λ…Έλ“œκ°€ λΆ€λͺ¨ λ…Έλ“œλ₯Ό 가리킨닀.
  • 트리의 루트λ₯Ό μ§‘ν•©μ˜ λŒ€ν‘œ μ›μ†Œλ‘œ μ‚ΌλŠ”λ‹€.

직관적인 그림으둜 보자.

트리λ₯Ό μ΄μš©ν•œ μ§‘ν•©μ˜ 처리

aλŠ” 자기 μžμ‹ μ„ 가리킀고 루트 λ…Έλ“œκ°€ λœλ‹€.

cλŠ” 자기 μžμ‹ μ„ 가리킀고 루트 λ…Έλ“œκ°€ 되며 μžμ‹ λ…Έλ“œ b와 hκ°€ ν–₯ν•˜κ³  μžˆλ‹€.

트리의 Union

트리λ₯Ό μ΄μš©ν•œ ν‘œν˜„μ—μ„œ 두 집합을 ν•©μΉ˜λŠ” μž‘μ—…μ€ μ—°κ²° 리슀트의 방법 보닀 μ•„μ£Ό κ°„λ‹¨ν•˜λ‹€.

두 집합 쀑 ν•œ 집합읠 γ…œνŠΈκ°€ λ‹€λ₯Έ μ§‘ν•©μ˜ 루트λ₯Ό 가리킀도둝 포인터 ν•˜λ‚˜λ§Œ λ³€κ²½ν•΄μ€€λ‹€λ©΄ 끝!

트리 μœ λ‹ˆμ˜¨

ν•˜λ‚˜μ˜ μ›μ†Œλ‘œ κ΅¬μ„±λœ 집합은 λ…Έλ“œλ₯Ό ν•˜λ‚˜ λ§Œλ“€κ³  이 λ…Έλ“œμ˜ λΆ€λͺ¨κ°€ μžμ‹ μ΄ λ˜λ„λ‘ 포인터λ₯Ό λ§Œλ“€μ–΄λ†“μœΌλ©΄ λœλ‹€.


// λΆ€λͺ¨ λ…Έλ“œ : p[x]

// λ…Έλ“œ xλ₯Ό μœ μΌν•œ μ›μ†Œλ‘œ ν•˜λŠ” 집합을 λ§Œλ“ λ‹€.
Make_Set(x){
    p[x] <- x;
}

// λ…Έλ“œ xκ°€ μ†ν•œ 집합과 λ…Έλ“œ yκ°€ μ†ν•œ 집합을 ν•©μΉœλ‹€.
Union(x, y){
    p[Find_Set(y)] <- Find_Set(x);
}

// λ…Έλ“œ xκ°€ μ†ν•œ 집합을 μ•Œμ•„λ‚Έλ‹€. λ…Έλ“œ xκ°€ μ†ν•œ 트리의 루트 λ…Έλ“œλ₯Ό λ¦¬ν„΄ν•œλ‹€.
Find_Set(x){
    if(x=p[x]) then return x;
    else return Find_Set(p[x])
}

μ—°μ‚°μ˜ νš¨μœ¨μ„ λ†’μ΄λŠ” 방법

 

랭크λ₯Ό μ΄μš©ν•œ Union

  • 각 λ…Έλ“œλŠ” μžμ‹ μ„ 루트둜 ν•˜λŠ” μ„œλΈŒνŠΈλ¦¬μ˜ 높이λ₯Ό RankλΌλŠ” μ΄λ¦„μœΌλ‘œ μ €μž₯ν•œλ‹€.
  • 단 ν•˜λ‚˜μ˜ λ…Έλ“œλ‘œ 된 트리의 λ†’μ΄λŠ” 0이라고 μ •μ˜ν•œλ‹€.
  • 루트 λ…Έλ“œμ˜ λž­ν¬κ°€ ν•΄λ‹Ή μ§‘ν•©μ˜ λž­ν¬κ°€ λœλ‹€.

 

경둜 μ••μΆ•

  • Find-Set을 ν–‰ν•˜λŠ” 과정에 경둜의 길이λ₯Ό μ€„μ΄λŠ” 아이디어이닀.
  • κΈ°λ³Έμ μœΌλ‘œλŠ” Find-Setκ³Ό 같이 ν–‰ν•˜λ˜ Find-Set(x)λ₯Ό μˆ˜ν–‰ν•˜λŠ” κ³Όμ •μ—μ„œ λ§Œλ‚˜λŠ” λͺ¨λ“  λ…Έλ“œκ°€ 직접 루트 λ…Έλ“œλ₯Ό 가리킀도둝 ν•œλ‹€.

 

λŒ“κΈ€