๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“š Algorithm/Algorithm Note

์•Œ๊ณ ๋ฆฌ์ฆ˜ - ์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ(Minimum Spanning Tree), ํฌ๋ฃจ์Šค์นผ(Kruskal), ํ”„๋ฆผ(Prim) Python ์ฝ”๋“œ

์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ (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 : ๊ฐ€์ค‘์น˜ ์ •๋ณด
728x90