์ต์ ์ ์ฅ ํธ๋ฆฌ (MST)
MST : Minimum Spanning Tree
๊ฐ์ ์ ๊ฐ์ค์น๋ฅผ ๊ณ ๋ คํ์ฌ ์ต์ ๋น์ฉ์ Spanning Tree๋ฅผ ์ ํํ๋ ๊ฒ
์ ์ฅ ํธ๋ฆฌ (Spanning Tree)
๊ทธ๋ํ ๋ด์ ๋ชจ๋ ์ ์ ์ ํฌํจํ๋ ํธ๋ฆฌ
๊ทธ๋ํ์ ์ต์ ์ฐ๊ฒฐ ๋ถ๋ถ ๊ทธ๋ํ ์ด๋ค. ์ต์ ์ฐ๊ฒฐ์ด๋, ๊ฐ์ ์ ์๊ฐ ๊ฐ์ฅ ์ ์ ๊ฒ์ด๋ค.
Spanning Tree์ ํน์ง
- DFS, BFS์ ์ด์ฉํ์ฌ ๊ทธ๋ํ์์ ์ ์ฅ ํธ๋ฆฌ๋ฅผ ์ฐพ์ ์ ์๋ค
- ํ๋์ ๊ทธ๋ํ์๋ ๋ง์ ์ ์ฅ ํธ๋ฆฌ๊ฐ ์กด์ฌํ ์ ์๋ค.
- Spanning Tree๋ ํธ๋ฆฌ์ ํน์ํ ํํ์ด๋ฏ๋ก ๋ชจ๋ ์ ์ ๋ค์ด ์ฐ๊ฒฐ ๋์ด ์์ด์ผ ํ๊ณ ์ฌ์ดํด์ ํฌํจํด์๋ ์๋๋ค.
MST (Minimum Spanning Tree)
๊ทธ๋ํ์์ ๋ชจ๋ ์ ์ ์ ์ฐ๊ฒฐํ๋, ์ฌ์ดํด์ด ์กด์ฌํ์ง ์๊ณ ๊ฐ์ ์ ๊ฐ์ค์น ํฉ์ด ์ต์์ธ ํธ๋ฆฌ
๐ MST์ ํน์ง
- ๊ฐ์ ์ ๊ฐ์ค์น์ ํฉ์ด ์ต์์ฌ์ผ ํ๋ค.
- n๊ฐ์ ์ ์ ์ ๊ฐ์ง๋ ๊ทธ๋ํ์ ๋ํด ๋ฐ๋์ (n-1)๊ฐ์ ๊ฐ์ ๋ง์ ์ฌ์ฉํด์ผ ํ๋ค.
- ์ฌ์ดํด์ด ํฌํจ๋์ด์๋ ์๋๋ค.
MST ๊ตฌํ ๋ฐฉ๋ฒ
1. Kruskal's Algorithm
greedy๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ ์ ํ ๋นํ ๊ทธ๋ํ์ ๋ชจ๋ ์ ์ ์ ์ต์ ๋น์ฉ์ผ๋ก ์ฐ๊ฒฐํด ๋๊ฐ๋ ๊ฒ
[๊ณผ์ ]
1. ๊ทธ๋ํ์ ๊ฐ์ ๋ค์ ๊ฐ์ค์น์ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ค.
2. ์ ๋ ฌ๋ ๊ฐ์ ๋ฆฌ์คํธ์์ ์์๋๋ก ์ฌ์ดํด์ ํ์ฑํ์ง ์๋ ๊ฐ์ ์ ์ ํํ๋ค.
- ์ฆ, ๊ฐ์ฅ ๋ฎ์ ๊ฐ์ค์น๋ฅผ ๋จผ์ ์ ํํ๋ค.
- ์ฌ์ดํด์ ํ์ฑํ๋ ๊ฐ์ ์ ์ ์ธํ๋ค.
3. ํด๋น ๊ฐ์ ์ ํ์ฌ์ MST(์ต์ ๋น์ฉ ์ ์ฅ ํธ๋ฆฌ)์ ์งํฉ์ ์ถ๊ฐํ๋ค.
def find(x):
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(a, b):
a = find(a)
b = find(b)
if a < b:
parent[b] = a
else:
parent[a] = b
v, e = map(int, input().split())
parent = [0] * (v + 1)
edges = []
result = 0
for i in range(1, v + 1):
parent[i] = i
for _ in range(e):
a, b, cost = map(int, input().split())
edges.append((cost, a, b))
edges.sort()
for edge in edges:
cost, a, b = edge
if find(a) != find(b):
union(a, b)
result += cost
print(result)
2. Prim Algorithm
์์ ์ ์ ์์ ์ถ๋ฐํ์ฌ ์ ์ฅ ํธ๋ฆฌ ์งํฉ์ ๋จ๊ณ์ ์ผ๋ก ํ์ฅํด ๋๊ฐ๋ ๊ฒ
[๊ณผ์ ]
1. ์์ ๋จ๊ณ์์๋ ์์ ์ ์ ๋ง์ด MST(์ต์ ๋น์ฉ ์ ์ฅ ํธ๋ฆฌ) ์งํฉ์ ํฌํจ๋๋ค.
2. ์ ๋จ๊ณ์์ ๋ง๋ค์ด์ง MST ์งํฉ์ ์ธ์ ํ ์ ์ ๋ค ์ค์์ ์ต์ ๊ฐ์ ์ผ๋ก ์ฐ๊ฒฐ๋ ์ ์ ์ ์ ํํ์ฌ ํธ๋ฆฌ๋ฅผ ํ์ฅํ๋ค.
-์ฆ, ๊ฐ์ฅ ๋ฎ์ ๊ฐ์ค์น๋ฅผ ๋จผ์ ์ ํํ๋ค.
3. ์์ ๊ณผ์ ์ ํธ๋ฆฌ๊ฐ (N-1)๊ฐ์ ๊ฐ์ ์ ๊ฐ์ง ๋๊น์ง ๋ฐ๋ณตํ๋ค.
INF = 9999 # ๊ฐ์ฅ ํฐ ๊ฐ์ค์น(๋ฌดํ๋)
# ํ์ฌ ํธ๋ฆฌ์ ์ธ์ ํ ์ ์ ๋ค ์ค์์ ๊ฐ์ฅ ๊ฐ๊น์ด ์ ์ ์ ์ฐพ๋ ํจ์
def getMinVertex(dist, selected):
minv = 0
mindist = INF
for v in range(len(dist)):
if not selected[v] and dist[v] < mindist:
mindist = dist[v]
minv = v
return minv
# Prim์ ์ต์ ๋น์ฉ ์ ์ฅ ํธ๋ฆฌ ํ๋ก๊ทธ๋จ
def MSTPrim(vertex, adj):
vsize = len(vertex)
dist = [INF] * vsize
selected = [False] * vsize
dist[0] = 0
for i in range(vsize):
u = getMinVertex(dist, selected)
selected[u] = True
print(vertex[u], end=' ')
for v in range(vsize):
if adj[u][v] != None:
if selected[v] == False and adj[u][v] < dist[v]:
dist[v] = adj[u][v]
print()
# vertex : ์ ์ ์ ์ ๋ณด
# weight : ๊ฐ์ค์น ์ ๋ณด