Union Find (ํฉ์งํฉ ์ฐพ๊ธฐ)
MST - 1
์ ๋ง ์ค๋๋ง์ ํฌ์คํ ์ด๋ค.
MST ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ๋ฅผ ํ๋ ๋์ค ์๊ฐ๋์ ํฌ์คํ ํ๊ฒ ๋๋ค.
๋งค์ฃผ ์ฃผ๋ง๋ง๋ค ์๊ณ ๋ฆฌ์ฆ ๊ฐ๋ ์ ๋ฆฌ๋ฅผ ํ๋ ค๊ณ ํ๋๋ฐ ๊ณ์ ์คํจํ๋ ๊ฒ ๊ฐ๋ค... ใ ใ ;;
์ค๋ ๋ค๋ค๋ณผ ์ฃผ์ ๋ MST, ์ต์ ์ ์ฅ ํธ๋ฆฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๊ธฐ๋ณธ ๋ฒ ์ด์ค์ธ Union Find์ด๋ค.
์ต์ ์ ์ฅ ํธ๋ฆฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์๋ ๋ํ์ ์ผ๋ก ํฌ๋ฃจ์ค์นผ(Kruskal)๊ณผ ํ๋ฆผ(Prim) ์๊ณ ๋ฆฌ์ฆ์ด ์กด์ฌํ๋ค.
Union FInd๋ ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ์ ํต์ฌ์ด๋ผ๊ณ ๋งํ ์ ์๋ค.
๊ทธ๋ผ Union Find๊ฐ ๋ฌด์์ธ์ง ์์๋ณด์.
Union Find๋ ๋ง ๊ทธ๋๋ก Union, ์งํฉ์ ์ฐพ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
๊ทธ๋ํ ์ ๋ณด๊ฐ ์ฃผ์ด์ก์ ๋ ์ด๋ค ๊ฐ์ ๊ด๊ณ๋ฅผ ์์๋ณผ ์ ์๋ค.
๋ฐ๋ก ์์๋ก ๋ค์ด๋ณด์.
์์ ๊ฐ์ ๊ทธ๋ํ ํํ๊ฐ ์ฃผ์ด์ก์ ๋ (1, 2, 3, 4)์ (5, 6)์ผ๋ก ๋ถ๋ฅํ ์ ์๋ค.
์ด๋ ๊ฒ ์งํฉ๋ณ๋ก ๋ถ๋ฅํ ์ ์๊ฒ ํด์ฃผ๋ ์๊ณ ๋ฆฌ์ฆ์ด Union Find์ด๋ค.
Union Find๋ฅผ ์งํํ๊ธฐ ์ํด์ Union๊ณผ Find, 2๊ฐ์ ํจ์๊ฐ ์ ์๋์ด์ผ ํ๋ค.
์ฐ์ Find๋ฅผ ๋จผ์ ์์๋ณด์.
Find๋ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ํ์ํ๋ ํจ์์ด๋ค.
parents๋ ํน์ ๋ ธ๋์ ๋ถ๋ชจ ๋ ธ๋๊ฐ ์ ์ฅ๋์ด ์๋ ๋ฆฌ์คํธ์ด๋ค.
์ฌ๊ท์ ์ผ๋ก ํธ์ถํ๋ฉด์ ๋ถ๋ชจ ๋ ธ๋ ๊ฐ์ ๋ฆฌํดํ๋ค.
def find_parent(parents, x):
if parents[x] != x:
parents[x] = find_parent(parents, parents[x])
return parents[x]
Union์ ๋ ๊ฐ์ ์์์ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ๋น๊ตํ๋ ํจ์์ด๋ค.
find๋ฅผ ์ด์ฉํด์ ๋ ์์์ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ์ฐพ์๋ด๊ณ ์ด๋ฅผ ๋น๊ตํ๋ค.
๊ฐ์ด ๊ฐ์ ๊ฒฝ์ฐ ์ฌ์ดํด์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ์ด๋ฏ๋ก 1์ ๋ฆฌํดํ๊ณ ํจ์๋ฅผ ์ข ๋ฃํ๋ค.
๊ฐ์ด ๋ค๋ฅธ ๊ฒฝ์ฐ ๋ ์์ ๊ฐ์ ๋ถ๋ชจ ๋ ธ๋๋ก ๋ง๋ค์ด์ค๋ค. ์ดํ 0์ ๋ฆฌํดํ๊ณ ํจ์๋ฅผ ์ข ๋ฃํ๋ค.
def union_parent(parents, x, y):
x = find_parent(parents, x)
y = find_parent(parents, y)
if x == y: # ์ฌ์ดํด์ด ๋ฐ์ํ ๊ฒฝ์ฐ
return 1
# ๊ฐ์ด ์์์๋ก ๋ ๋ฎ์ ๋ ๋ฒจ์ ๋
ธ๋
if x > y:
parents[x] = y # x์ ๋ถ๋ชจ ๋
ธ๋๋ฅผ y๋ก ๋ฐ๊ฟ์ค๋ค.
else:
parents[y] = x # y์ ๋ถ๋ชจ ๋
ธ๋๋ฅผ x๋ก ๋ฐ๊ฟ์ค๋ค.
return 0 # ์ ์์ ์ผ๋ก ํฉ์ณ์ง ๊ฒฝ์ฐ
๊ฐ์ด ๊ฐ์ ๊ฒฝ์ฐ ์ฌ์ดํด์ด ์กด์ฌํ๋ค๊ณ ํ๋จํ๋ ๋ถ๋ถ์ด ์ดํด๊ฐ ๋์ง ์์์๋ ์๋ค.
์๋ฅผ ๋ค์ด ์๋์ ๊ฐ์ด ์ ๋ ฅ ๊ฐ์ด ์ฃผ์ด์ง ๊ฒฝ์ฐ
3 2 # ๋
ธ๋ ๊ฐ์, ๊ฐ์ ๊ฐ์
1 2
1 3
2์ ๋ถ๋ชจ ๋ ธ๋๋ 1์ด๊ณ 3์ ๋ถ๋ชจ ๋ ธ๋๋ 1์ธ๋ฐ? ์ฌ์ดํด๋ก ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋์ด์ผํ๋ ๊ฒ์ด ์๋๊ฐ?
ํ์ง๋ง ์ด๊ธฐ์ ๋ถ๋ชจ ๋ ธ๋๊ฐ ๋ด๊ธด ๋ฆฌ์คํธ๋ฅผ ์๊ธฐ ์์ ์ผ๋ก ์ด๊ธฐํ ์์ผ์ฃผ์๊ธฐ ๋๋ฌธ์
์ฒ์ ๋ฐฉ๋ฌธํ๋ ๋ ธ๋์ธ ๊ฒฝ์ฐ ๊ทธ ๊ฐ์ด ์๊ธฐ ์์ ์ผ ๊ฒ์ด๋ค. ๋ฐ๋ผ์ if๋ฌธ ์กฐ๊ฑด์ ๊ฑธ๋ฆฌ์ง ์๋๋ค.
์ด๊ฒ ๋์ด๋ค. ๋ชจ๋ ๋ ธ๋์ ๋ํด Union๊ณผ Find๋ฅผ ํด์ฃผ๋ฉด ๋๋ค.
์์์ ๋งํ ๋จ๊ณ์ ์ผ๋ก ์งํํด๋ณด์.
1. ์๊ธฐ ์์ ์ ๋ถ๋ชจ ๋ ธ๋๋ก ์ค์ ํด์ค๋ค.
ํ์ฌ ๋ ธ๋ | 1 | 2 | 3 | 4 | 5 | 6 |
๋ถ๋ชจ ๋ ธ๋ | 1 | 2 | 3 | 4 | 6 | 6 |
์ฐ์ ํน์ ๋ ธ๋์ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ์๊ธฐ ์์ ์ผ๋ก ์ค์ ํด์ค ํ์๊ฐ ์๋ค. (์ด๊ธฐํ)
2. ๋ ธ๋๋ฅผ ํ์ํ๋ฉด์ ๋ ๋ ธ๋์ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ๋น๊ตํ๋ค. ๋ ์์ ๋ ธ๋๋ฅผ ๋ถ๋ชจ ๋ ธ๋๋ก ์ ํด์ค๋ค.
3. ๋ ์์์ ๋ถ๋ชจ ๋ ธ๋๊ฐ ๊ฐ์ ๊ฒฝ์ฐ ์ด๋ ์ฌ์ดํด์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ์ด๋ฏ๋ก ์ข ๋ฃํ๋ค.
์์ ๊ฐ๋ ์ ํ์ด์ฌ์ผ๋ก ๊ตฌํํด๋ณด์๋ค.
def find_parent(parents, x):
if parents[x] != x:
parents[x] = find_parent(parents, parents[x])
return parents[x]
def union_parent(parents, x, y):
x = find_parent(parents, x)
y = find_parent(parents, y)
if x == y: # ์ฌ์ดํด์ด ๋ฐ์ํ ๊ฒฝ์ฐ
return 1
# ๊ฐ์ด ์์์๋ก ๋ ๋ฎ์ ๋ ๋ฒจ์ ๋
ธ๋
if x > y:
parents[x] = y # x์ ๋ถ๋ชจ ๋
ธ๋๋ฅผ y๋ก ๋ฐ๊ฟ์ค๋ค.
else:
parents[y] = x # y์ ๋ถ๋ชจ ๋
ธ๋๋ฅผ x๋ก ๋ฐ๊ฟ์ค๋ค.
return 0 # ์ ์์ ์ผ๋ก ํฉ์ณ์ง ๊ฒฝ์ฐ
def main():
n, m = map(int, input().split())
nodes = [[] for _ in range(n+1)] # 1 ~ n๊น์ง์ ๋
ธ๋ ์ ๋ณด๋ฅผ ์ ์ฅํ ๋ฆฌ์คํธ
parents = [i for i in range(n+1)] # ๋ถ๋ชจ๋
ธ๋๋ฅผ ์ ์ฅํ ๋ฆฌ์คํธ -> ์ด๊ธฐ๊ฐ์ ์๊ธฐ ์์
for _ in range(m):
src, dst = map(int, input().split())
nodes[src].append(dst)
cycleCheck = False
for i in range(1, n+1):
for j in nodes[i]:
if union_parent(parents, i, j) == 1:
cycleCheck = True
break
if cycleCheck:
print("์ฌ์ดํด์ด ๋ฐ์ํ์ต๋๋ค!")
else:
print(parents[1:])
if __name__ == "__main__":
main()
์คํ ๊ฒฐ๊ณผ ๋ถ๋ชจ ๋ ธ๋๋ฅผ ์ ํํ๊ฒ ํ์ํ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ค์ ์๊ฐ์ Union Find๋ฅผ ์ด์ฉํ์ฌ MST๋ฅผ ๊ณ์ฐํ๋ ์๊ณ ๋ฆฌ์ฆ์ธ Kruskal์ ๋ํด ํฌ์คํ ์ ํด๋ณด๊ฒ ๋ค.
'โ๏ธ ์๊ณ ๋ฆฌ์ฆ > Graph' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
5. Floyd Warshall(ํ๋ฃจ์ด๋ ์์ฌ) : ์ต๋จ ๊ฒฝ๋ก ํ์ - 3 (0) | 2021.03.31 |
---|---|
4. Bellman-Ford(๋ฒจ๋ง ํฌ๋) : ์ต๋จ ๊ฒฝ๋ก ํ์ - 2 (0) | 2021.03.07 |
3. Dijsktra(๋ค์ต์คํธ๋ผ) : ์ต๋จ ๊ฒฝ๋ก ํ์ - 1 (0) | 2021.03.02 |
2. DFS(Depth-Find-Search) : ๊น์ด ์ฐ์ ํ์ (0) | 2021.01.22 |
1. BFS(Breath-Find-Search) : ๋๋น ์ฐ์ ํ์ (0) | 2021.01.21 |