์ž๋ฃŒ๊ตฌ์กฐ/๐Ÿ‘‰์•Œ๊ณ ๋ฆฌ์ฆ˜ - 27

์˜ค๋Š˜ ๋“ค์€ ๊ฐ•์˜ ๋ชฉ๋ก

  1. ํ”„๋ฆผ - 4
  2. ๊ฐœ์„  ํ”„๋ฆผ - 1

ํ”„๋ฆผ ์‹œ๊ฐ„๋ณต์žก๋„

while connected_e:
    next_e = heappop(connected_e)
    if next_e[2] not in connected_n:
        tree.append(next_e)
        connected_n.add(next_e[2])
        for edge in edgesOf[next_e[2]]: # E, ๋‹ค ์ถ”๊ฐ€
            if edge[2] not in connected_n:
                heappush(connected_e, edge) # log E

๋ชจ๋“  ๊ฐ„์„  ์ถ”๊ฐ€ -> $E$

ํž™ push -> $log E$

์‹œ๊ฐ„๋ณต์žก๋„ : $O(E log E)$

ํ”„๋ฆผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ฐœ์„ 

๋Œ€๋ถ€๋ถ„ $O(E log V)$์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๋Š” ํ”„๋ฆผ ์•Œ๊ณ ๋ฆฌ์ฆ˜

๊ฐ„์„ ์ด ์•„๋‹Œ ๋…ธ๋“œ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์ ์šฉ

  1. ํž™์— ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋„ฃ๊ณ , key๋Š” ๋ฌดํ•œ๋Œ€๋กœ ์ดˆ๊ธฐํ™” (key = ๊ฐ€์ค‘์น˜)
  2. ํž™์— ์žˆ๋Š” ์‹œ์ž‘ ๋…ธ๋“œ์˜ key๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™”(heapdict๋ฅผ ์ด์šฉ, decrease-key)
    ์ด๋•Œ ์ด์ „ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ• ๋•Œ ์ด์ „๋…ธ๋“œ๋ฅผ ์‹œ์ž‘๋…ธ๋“œ๋กœ ํ•œ๋‹ค.
  3. ํž™์—์„œ ๋…ธ๋“œ๋ฅผ ๋ฝ‘๊ณ , ์„ ํƒํ•œ๋‹ค.
  4. ์„ ํƒํ•œ ๋…ธ๋“œ์— ์—ฐ๊ฒฐ๋œ ๊ฐ„์„ ๋“ค์— ๋Œ€ํ•ด 5๋ฒˆ์„ ์ง„ํ–‰ํ•œ๋‹ค.
  5. ๊ฐ ๊ฐ„์„ ์— ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋ฅผ ํ™•์ธํ•˜๊ณ ,
    ํ•ด๋‹น ๊ฐ„์„ ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ํž™์— ์žˆ๋Š” ํ•ด๋‹น ๋…ธ๋“œ์˜ ๊ฐ€์ค‘์น˜๋ณด๋‹ค ์ž‘์œผ๋ฉด, ํž™์˜ ๊ฐ€์ค‘์น˜๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.
  6. ํž™์— ๋…ธ๋“œ๊ฐ€ ์—†์„ ๋•Œ๊นŒ์ง€ 3๋ฒˆ~5๋ฒˆ์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
from heapdict import heapdict
def advprim(edges, start_node):
    tree = []
    # ๊ฐ ๋…ธ๋“œ๋ณ„๋กœ ์—ฐ๊ฒฐ๋œ ๊ฐ„์„ ์„ ์ •๋ฆฌ
    # ๊ทธ๋ž˜ํ”„ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค๋•Œ ์ด๋Ÿฐ ๊ตฌ์กฐ๋กœ ๋งŒ๋“œ๋Š”๊ฒŒ ๊ตญ๋ฃฐ์ด์ง€๋งŒ ์ด์ „์ฝ”๋“œ ์žฌ์‚ฌ์šฉํ•˜๋А๋ผ..
    edgesOf = defaultdict(list)
    for weight, n1, n2 in edges:
        edgesOf[n1].append((weight, n1, n2))
        edgesOf[n2].append((weight, n2, n1))
    # ๋…ธ๋“œ๊ฐ€ ๋“ค์–ด์žˆ๋Š” ํž™ ์ดˆ๊ธฐํ™”
    n_heap = heapdict()
    for node in edgesOf:
        n_heap[node] = float('inf')
    n_heap[start_node] = 0
    before = {node : None for node in edgesOf}
    before[start_node] = start_node
    
    while n_heap:
        cur_n, cur_k = n_heap.popitem()
        prev_n = before[cur_n]
        tree.append([prev_n, cur_n, cur_k])
        for w, c, n in edgesOf[cur_n]:
            if n in n_heap and w < n_heap[n]:
                n_heap[n] = w
                before[n] = cur_n
        
    return tree

prim

result

์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” ์ด์ „์— ๊ธฐ๋ณธ ํ”„๋ฆผ ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ๋Š” ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ ๋‚˜์™”๋‹ค.

๊ฒ€์€์ƒ‰์œผ๋กœ ์น ํ•œ 7์˜ ๊ฐ€์ค‘์น˜๋ฅผ ๊ฐ€์ง„ ๊ฐ„์„  ๋Œ€์‹ ,
ํŒŒ๋ž€์ƒ‰์œผ๋กœ ์น ํ•œ 7์˜ ๊ฐ€์ค‘์น˜๋ฅผ ๊ฐ€์ง„ ๊ฐ„์„ ์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๊ฐ€์ค‘์น˜๊ฐ€ ๊ฐ™์•„์„œ mst์˜ ๊ฐ€์ค‘์น˜ ํ•ฉ์€ ๊ฐ™๋‹ค.

heapdict?

ํž™ ๊ตฌ์กฐ์—์„œ ์ด๋ฏธ ์‚ฝ์ž…๋˜์–ด์žˆ๋Š” ๋…ธ๋“œ์˜ key๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ, ํž™ ๊ตฌ์กฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•  ๋•Œ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“ˆ
์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ํž™ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•œ๋‹ค.(decrease-key)

hd = heapdict()
hd[obj1] = priority1
hd[obj2] = priority2
print(hd.peakitem())
(obj, priority) = hd.popitem()

์œ„์˜ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งˆ์ง€๋ง‰

ํ”„๋ฆผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ฒ˜์Œ๊ตฌํ˜„ํ•ด๋ด์„œ ๊ฐ•์˜์—์„œ ์ฃผ์–ด์ง„ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ–ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ฃผ์„์œผ๋กœ ์ž‘์„ฑํ–ˆ๋“ฏ์ด ๊ทธ๋ž˜ํ”„ ๊ตฌ์กฐ๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ,(ํ•จ์ˆ˜์— ๋„˜๊ฒจ์ฃผ๊ธฐ ์ „์—)
๊ตฌ์กฐ๋ฅผ ์ž˜ ๋งŒ๋“ค์–ด์„œ ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋‹ค์‹œ ๊ณ ์น˜์ง€ ์•Š๋„๋ก ํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

์ˆ˜๊ฐ•

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ