๊ด€๋ฆฌ ๋ฉ”๋‰ด

Keep Going

[์ตœ๋‹จ๊ฑฐ๋ฆฌ] ๋ฒจ๋งŒ ํฌ๋“œ ๋ณธ๋ฌธ

Problem Solving

[์ตœ๋‹จ๊ฑฐ๋ฆฌ] ๋ฒจ๋งŒ ํฌ๋“œ

seon 2024. 6. 10.
๋ฐ˜์‘ํ˜•

๋ฒจ๋งŒ ํฌ๋“œ ํŠน์ง•

    • ์šฉ๋„: ๋‹จ์ผ ์ถœ๋ฐœ์ ์—์„œ ๋ชจ๋“  ์ •์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • ๊ทธ๋ž˜ํ”„ ์œ ํ˜•: ์Œ์˜ ๊ฐ€์ค‘์น˜๋ฅผ ํ—ˆ์šฉํ•˜๋ฉฐ, ์Œ์˜ ์‚ฌ์ดํด๋„ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์Œ
    • ์žฅ์ : ์Œ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์žˆ๋Š” ๊ทธ๋ž˜ํ”„์—์„œ๋„ ๋™์ž‘ํ•˜๋ฉฐ, ์Œ์˜ ์‚ฌ์ดํด์„ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์Œ
    • ๋‹จ์ : ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋ณด๋‹ค ๋†’์Œ. So, ์Œ์ˆ˜ ๊ฐ€์ค‘์น˜ ์ƒํ™ฉ์—์„œ๋Š” SPFA ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋” ํšจ์œจ์  !!

์•Œ๊ณ ๋ฆฌ์ฆ˜

์‹œ๊ฐ„ ๋ณต์žก๋„ O(VE)
: ๋ชจ๋“  ๊ฐ„์„ ์— ๋Œ€ํ•ด V-1๋ฒˆ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์‹ ํ•˜๋Š” ํ•ต์‹ฌ ์•Œ๊ณจ ํŒŒํŠธ๊ฐ€ ์‹œ๊ฐ„ ๋ณต์žก๋„์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ , ์ด๋Š” O(VE)์ด๋‹ค.
for _ in range(n - 1): # O(V-1)
    for u, v, w in edges: # O(E)
        if dist[u] != float('inf') and dist[u] + w < dist[v]:
            dist[v] = dist[u] + w
 ์•„์ด๋””์–ด
: ๊ทธ๋ž˜ํ”„์˜ ๋ชจ๋“  ๊ฐ„์„ ์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ๊ฒ€์‚ฌํ•ด์„œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์‹ ํ•œ๋‹ค. ๋…ธ๋“œ V๊ฐœ์— ๋Œ€ํ•ด V-1๋ฒˆ์˜ ๋ฐ˜๋ณต์„ ํ•œ ํ›„์—๋„ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐฑ์‹ ๋˜๋ฉด, ์Œ์˜ ์‚ฌ์ดํด์ด ์กด์žฌํ•œ๋‹ค๊ณ  ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.

 

1. ์ตœ๋‹จ๊ฑฐ๋ฆฌ ๋ฐฐ์—ด ์ดˆ๊ธฐํ™”

  • dist = [int(1e9)]*n
  • ์ถœ๋ฐœ ์ง€์ ์˜ dist๋Š” 0์œผ๋กœ ์ดˆ๊ธฐํ™”
dist = [int(1e9)] * n
dist[start] = 0

2. ๋ชจ๋“  ๊ฐ„์„ ์— ๋Œ€ํ•ด ๋ฐ˜๋ณต์ ์œผ๋กœ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ฐฑ์‹ 

  • ๋ชจ๋“  ๊ฐ„์„ ์„ V-1 ๋ฒˆ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์‹ ํ•œ๋‹ค.
    • ์™œ V-1๋ฒˆ ๋ฐ˜๋ณตํ•˜์ฃ ??
      • ์ตœ๋‹จ ๊ฒฝ๋กœ๋Š” ์ตœ๋Œ€ V-1๊ฐœ์˜ ๊ฐ„์„ ์„ ํฌํ•จํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
      • : ๊ทธ๋ž˜ํ”„์— V๊ฐœ์˜ ์ •์ ์ด ์žˆ๋‹ค๋ฉด ๋‘ ์ •์  ์‚ฌ์ด์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ์—๋Š” ์ตœ๋Œ€ V-1๊ฐœ์˜ ๊ฐ„์„ ์„ ๋ชจ๋‘ ๊ฑฐ์ณ๊ฐ€๋Š” ๊ฒฝ์šฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
      • ๊ทธ๋ž˜์„œ ๋ชจ๋“  ์ •์ ์— ๋Œ€ํ•ด V-1๋ฒˆ ๋ฐ˜๋ณตํ•˜๋ฉด ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๊ฑฐ๋ฆฌ ๊ฐฑ์‹  ๊ธฐ์ค€์€ ๋ญ์ฃ ??
      1. dist[u] != int(1e9) ์ด๊ณ  !!: ์œ ํšจํ•˜์ง€ ์•Š์œผ๋ฉด(=int(1e9)) v๊นŒ์ง€ ๊ฐ€๋Š” ๊ฒฝ๋กœ๋ฅผ ๊ณ„์‚ฐํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๋ถˆํ•„์š” ํ•œ ์—ฐ์‚ฐ์„ ํ•˜์ง€ ๋ง์ž
      2. : (์‹œ์ž‘๋…ธ๋“œ,๋„์ฐฉ๋…ธ๋“œ,๊ฐ€์ค‘์น˜) = (u,v,w) ์ผ ๋•Œ, v ๋…ธ๋“œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์‹ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋ผ๋ฉด u๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๊ฐ€ ์œ ํšจํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ž˜์•ผ ๊ณ„์‚ฐํ•ด์„œ ๋ญ ์–ด์ฐŒํ•˜๋“  ํ•˜์ง€ !!
      3. dist[u] + weight < dist[v]์ด๋ฉด
      4. dist[v]๋ฅผ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์‹œ์ž‘ ์ •์ ์—์„œ u๋ฅผ ๊ฑฐ์ณ v๋กœ ๊ฐ€๋Š” ๊ฒฝ๋กœ๊ฐ€ ๋” ์งง๋‹ค๋ฉด, ์ด๋ฅผ ๋ฐ˜์˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
for _ in range(n - 1):
    for u, v, w in edges:
        if dist[u] != int(1e9) and dist[u] + w < dist[v]:
            dist[v] = dist[u] + w

3. ์Œ์˜ ์‚ฌ์ดํด ์กด์žฌ ํŒ๋‹จํ•˜๊ธฐ

  • V-1๋ฒˆ ๋ฐ˜๋ณต ํ›„์—๋„ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐฑ์‹ ์ด ๋œ๋‹ค๋ฉด, ์ด๊ฒƒ์€ ์Œ์˜ ์‚ฌ์ดํด์ด ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. (์™œ๋ƒ๋ฉด, ์Œ์˜ ์‚ฌ์ดํด์€ ๋Œ๋ฉด์„œ ๋์—†์ด ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ฒŒ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.)
  • ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํŒ๋‹จํ•˜๋Š” ๋กœ์ง๊ณผ ๋™์ผํ•˜๋‹ค. ์ด๋ฏธ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฒจ๋งŒํฌ๋“œ ์‹คํ–‰์„ ๋ชจ๋‘ ๋๋‚œ ํ›„์— !!!! ์ด ์Œ์˜ ์‚ฌ์ดํด ์กด์žฌ ํŒ๋‹จ ๋กœ์ง์„ ๋Œ๋ฆฌ๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์—ฌ๊ธฐ์„œ if๋ฌธ์„ ํ†ต๊ณผํ•œ๋‹ค๋Š” ๊ฒƒ์€ !!! ๋˜ ๋‹ค๋ฅธ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ด๊ณ  = ์ด๋Š” ์ฆ‰, ์Œ์˜ ์‚ฌ์ดํด์ด ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค !!!
for u, v, w in edges:
    if dist[u] != float('inf') and dist[u] + w < dist[v]:
        print("Graph contains a negative weight cycle")
        return None

๊ตฌํ˜„

def bellman_ford(n, edges, start):
    # ๊ฑฐ๋ฆฌ ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™”
    dist = [float('inf')] * n
    dist[start] = 0

    # ๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜
    for i in range(n - 1):
        for u, v, w in edges:
            if dist[u] != float('inf') and dist[u] + w < dist[v]:
                dist[v] = dist[u] + w

    # ์Œ์˜ ์‚ฌ์ดํด ๊ฒ€์ถœ
    for u, v, w in edges:
        if dist[u] != float('inf') and dist[u] + w < dist[v]:
            print("Graph contains a negative weight cycle")
            return None

    return dist

# ์˜ˆ์ œ ๊ทธ๋ž˜ํ”„
n = 5
edges = [
    (0, 1, -1),
    (0, 2, 4),
    (1, 2, 3),
    (1, 3, 2),
    (1, 4, 2),
    (3, 2, 5),
    (3, 1, 1),
    (4, 3, -3)
]

start = 0
distances = bellman_ford(n, edges, start)
if distances:
    print(distances)

SPFA ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํŠน์ง•

  • SPFA(Shortest Path Faster Algorithm)
  • ๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ฐœ์„ ๋œ ๋ฒ„์ „์œผ๋กœ, ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์— ๋” ๋น ๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š” ๋‹จ์ผ ์ถœ๋ฐœ์  ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜
  • SPFA ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์Œ์ˆ˜ ๊ฐ€์ค‘์น˜๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์Œ์˜ ์‚ฌ์ดํด๋„ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ๋ฅผ ์‚ฌ์šฉํ•œ ์ตœ์ ํ™”:
    • ๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ชจ๋“  ๊ฐ„์„ ์„ ๋งค ๋ฐ˜๋ณต๋งˆ๋‹ค ๊ฒ€์‚ฌํ•˜์ง€๋งŒ, SPFA ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐฑ์‹ ์ด ํ•„์š”ํ•œ ์ •์ ๋งŒ ํ์— ๋„ฃ๊ณ , ํ์—์„œ ๊บผ๋‚ด์„œ ๊ทธ ์ •์ ๊ณผ ์—ฐ๊ฒฐ๋œ ๊ฐ„์„ ๋“ค๋งŒ ๊ฒ€์‚ฌํ•˜๊ธฐ์— ๋” ํšจ์œจ์ ์ด๋‹ค.
  • ์ค‘๋ณต ๊ฒ€์‚ฌ๋ฅผ ์ค„์ž„:
    • ๋ฒจ๋งŒ ํฌ๋“œ ์ฒ˜๋Ÿผ ๋งค๋ฒˆ V-1๋ฒˆ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, queue๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ์—์„œ ๊บผ๋‚ธ ์ •์ ๊ณผ ์—ฐ๊ฒฐ๋œ ๊ฐ„์„ ๋งŒ ํ™•์ธํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐฑ์‹ ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ •์ ์„ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.
  • ์Œ์˜ ์‚ฌ์ดํด ๊ฐ์ง€:
    • ๊ฐ ์ •์ ์ด ํ์— ๋ช‡ ๋ฒˆ ๋“ค์–ด๊ฐ”๋Š”์ง€๋ฅผ ๊ธฐ๋กํ•˜์—ฌ ์Œ์˜ ์‚ฌ์ดํด์„ ๊ฐ์ง€ํ•œ๋‹ค.

์•Œ๊ณ ๋ฆฌ์ฆ˜

์‹œ๊ฐ„๋ณต์žก๋„ O(VE)

: ์ตœ์•…์˜ ๊ฒฝ์šฐ O(VE)์ด์ง€๋งŒ, ํ‰๊ท ์ ์œผ๋กœ๋Š” ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์ž‘๋™ํ•œ๋‹ค. ํ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐฑ์‹ ์ด ํ•„์š”ํ•œ ๋…ธ๋“œ๋งŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค์ œ ์ˆ˜ํ–‰ ์‹œ๊ฐ„์ด ๋ฒจ๋งŒ ํฌ๋“œ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋ณด๋‹ค ํ›จ์”ฌ ๋‚ฎ๋‹ค.

1. ์ตœ๋‹จ๊ฑฐ๋ฆฌ ๋ฐฐ์—ด ์ดˆ๊ธฐํ™”

dist = [int(1e9)] * n
dist[start] = 0

2. ํ ์ดˆ๊ธฐํ™”, ์Œ์˜ ์‚ฌ์ดํด ํƒ์ง€๋ฅผ ์œ„ํ•œ count ์ดˆ๊ธฐํ™”

  • ์‹œ์ž‘ ๋…ธ๋“œ๋ฅผ ํ์— ์ถ”๊ฐ€ํ•˜๊ณ ,
  • n๊ฐœ์— ๋…ธ๋“œ์— ๋Œ€ํ•ด ๋‹ค queue์— ์—†๋‹ค๊ณ  False๋กœ ์ดˆ๊ธฐํ™” ํ•˜๊ณ 
  • ์‹œ์ž‘ ๋…ธ๋“œ๋Š” queue์— ์žˆ๋‹ค๊ณ  True ๋งŒ๋“ค์–ด์ฃผ๊ธฐ
from collections import deque

queue = deque([start])
in_queue = [False] * n
in_queue[start] = True

count = [0] * n # ์Œ์˜ ์‚ฌ์ดํด ๊ฐ์ง€๋ฅผ ์œ„ํ•œ count ๋ฐฐ์—ด ์ตœ๊ณ ํ•˜

3. ํ๋ฅผ ์‚ฌ์šฉํ•œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ฐฑ์‹ 

  • ํ์—์„œ ๋…ธ๋“œ๋ฅผ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ธ๋‹ค. ๊บผ๋ƒˆ์œผ๋ฉด in_queue[]=False ์ฒ˜๋ฆฌ
  • ๊ทธ ๋…ธ๋“œ๊ณผ ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ๊ฐ„์„ ์„ ๊ฒ€์‚ฌํ•œ๋‹ค.
  • ๊ฐ ๊ฐ„์„ ์„ ํ†ตํ•ด ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๊ฐ€ ๊ฐฑ์‹  ๋˜๋ฉด ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ํ์— append & in_queue=True
while queue:
    u = queue.popleft()  # ํ์—์„œ ์ •์ ์„ ํ•˜๋‚˜ ๊บผ๋ƒ„
    in_queue[u] = False  # ํ์— ๋” ์ด์ƒ ์ด ์ •์ ์ด ์—†์Œ์„ ํ‘œ์‹œ

    for v, w in edges[u]:  # ์ •์  u์™€ ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ๊ฐ„์„  ๊ฒ€์‚ฌ
      if dist[u] + w < dist[v]:  # ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ฐฑ์‹  ์กฐ๊ฑด
          dist[v] = dist[u] + w  # ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ฐฑ์‹ 
          if not in_queue[v]:  # ์ •์  v๊ฐ€ ํ์— ์—†๋‹ค๋ฉด
              queue.append(v)  # ํ์— ์ถ”๊ฐ€
              in_queue[v] = True  # ํ์— ์ถ”๊ฐ€๋˜์—ˆ์Œ์„ ํ‘œ์‹œ

4. ์Œ์˜ ์‚ฌ์ดํด ๊ฐ์ง€

  • ๊ฐ ๋…ธ๋“œ๊ฐ€ ํ์— ๋ช‡ ๋ฒˆ ๋“ค์–ด๊ฐ”๋Š”์ง€๋ฅผ ๊ธฐ๋กํ•˜์—ฌ, ๋…ธ๋“œ๊ฐ€ V๋ฒˆ ์ด์ƒ ํ์— ๋“ค์–ด๊ฐ€๋ฉด ์Œ์˜ ์‚ฌ์ดํด์ด ์กด์žฌํ•œ๋‹ค๊ณ  ํŒ๋‹จํ•œ๋‹ค.
    • ์™œ๋ƒํ•˜๋ฉด, ์ตœ๋Œ€ V๋ฒˆ ์ด์ƒ ํ์— ๋“ค์–ด๊ฐ”๋‹ค๋Š” ๊ฒƒ์€, ํ•ด๋‹น ๋…ธ๋“œ์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๊ฐ€ V-1๋ฒˆ ์ด์ƒ์˜ ๊ฐฑ์‹  ๊ณผ์ •์„ ๊ฑฐ์ณค๋‹ค๋Š” ๋œป์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
      • ์•„ํ•˜ ํ์— ๋“ค์–ด๊ฐ€๋ฉด ๋“ค์–ด๊ฐ„ ํšŸ์ˆ˜๊ฐ€ +1 ์ด๊ณ , ํ์— ๋„ฃ์€ ๋‹ค์Œ์— ์Œ์˜ ์‚ฌ์ดํด ๊ฐ์ง€๋ฅผ ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— V์ด๊ตฌ๋‚˜???
# queue์— appendํ•œ ์ดํ›„์— ์•„๋ž˜ ๋กœ์ง ์ˆ˜ํ–‰

if in_queue[v]:
    count[v] += 1
    if count[v] >= n:  # ์Œ์˜ ์‚ฌ์ดํด ๊ฐ์ง€
        print("Graph contains a negative weight cycle")
        return None

๊ตฌํ˜„

from collections import deque

def spfa(n, edges, start):
    dist = [float('inf')] * n
    in_queue = [False] * n
    count = [0] * n
    count[start] = 1

    dist[start] = 0
    queue = deque([start])
    in_queue[start] = True

    while queue:
        u = queue.popleft()
        in_queue[u] = False # queue์— ์—†์Šต๋‹ˆ๋‹น

        for v, w in edges[u]:
            if dist[u] + w < dist[v]:
                dist[v] = dist[u] + w
                if not in_queue[v]:
                    queue.append(v)
                    in_queue[v] = True # queue์— ์žˆ์Šต๋‹ˆ๋‹น

                    # ์Œ์˜ ์‚ฌ์ดํด ๊ณ„์‚ฐ์„ ์œ„ํ•œ ์ฝ”๋“œ
                    count[v] += 1
                    if count[v] > n-1:  # ์Œ์˜ ์‚ฌ์ดํด ๊ฐ์ง€
                        print("Graph contains a negative weight cycle")
                        return None

    return dist

# ์˜ˆ์ œ ๊ทธ๋ž˜ํ”„
n = 5
edges = {
    0: [(1, -1), (2, 4)],
    1: [(2, 3), (3, 2), (4, 2)],
    2: [],
    3: [(2, 5), (1, 1)],
    4: [(3, -3)]
}

start = 0
distances = spfa(n, edges, start)
if distances:
    print(distances)

์ด๋Ÿฐ ๊ทธ๋ž˜ํ”„์—์„œ ํŠนํžˆ ์ข‹์Šต๋‹ˆ๋‹น

1. ํฌ์†Œ ๊ทธ๋ž˜ํ”„(Sparse Graph):

  • ์ •์ ์˜ ์ˆ˜์— ๋น„ํ•ด ๊ฐ„์„ ์˜ ์ˆ˜๊ฐ€ ์ ์€ ๊ทธ๋ž˜ํ”„.
  • SPFA ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ฑฐ๋ฆฌ ๊ฐฑ์‹ ์ด ํ•„์š”ํ•œ ์ •์ ๋งŒ ํ์— ๋„ฃ์–ด ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ, ์ „์ฒด ๊ฐ„์„ ์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š์•„์„œ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
  • ํฌ์†Œ ๊ทธ๋ž˜ํ”„/๋ฐ€์ง‘ ๊ทธ๋ž˜ํ”„ ํŒ๋‹จ ์ˆ˜์‹
    • ํฌ์†Œ ๊ทธ๋ž˜ํ”„:
      • ๊ฐ„์„ ์˜ ์ˆ˜ E๊ฐ€ ์ •์ ์˜ ์ˆ˜ V์— ๋น„ํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ์ ์€ ๊ทธ๋ž˜ํ”„.
      • ์ผ๋ฐ˜์ ์œผ๋กœ E≤O(VlogV) ๋˜๋Š” E≈O(V)๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. (V=1000, E=2000)
    • ๋ฐ€์ง‘ ๊ทธ๋ž˜ํ”„:
      • ๊ฐ„์„ ์˜ ์ˆ˜ E๊ฐ€ ์ •์ ์˜ ์ˆ˜ V์— ๋น„ํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ๋งŽ์€ ๊ทธ๋ž˜ํ”„.
      • ์ผ๋ฐ˜์ ์œผ๋กœ E≈O(V^2)๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค.
    • ํฌ์†Œ ๊ทธ๋ž˜ํ”„:
      • ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ(Adjacency List)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ณต๊ฐ„ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
      • ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ๋‹ค์ต์ŠคํŠธ๋ผ(Dijkstra) ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•  ๋•Œ๋„ ํž™์„ ์‚ฌ์šฉํ•˜์—ฌ ํšจ์œจ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      • SPFA ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ํšจ์œจ์ ์œผ๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๋ฐ€์ง‘ ๊ทธ๋ž˜ํ”„:
      • ์ธ์ ‘ ํ–‰๋ ฌ(Adjacency Matrix)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ณต๊ฐ„ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
      • ํ”Œ๋กœ์ด๋“œ-์›Œ์…œ(Floyd-Warshall) ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ ํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2. ๊ฑฐ๋ฆฌ๊ฐ€ ์ž์ฃผ ๊ฐฑ์‹  ๋˜์ง€ ์•Š๋Š” ๊ทธ๋ž˜ํ”„:

  • ๊ฑฐ๋ฆฌ ๊ฐฑ์‹ ์ด ๋นˆ๋ฒˆํ•˜์ง€ ์•Š์€ ๊ทธ๋ž˜ํ”„.
  • ํ์— ์ถ”๊ฐ€๋˜๋Š” ์ •์ ์˜ ์ˆ˜๊ฐ€ ์ ์–ด์ ธ ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์ด ์ค„์–ด๋“ค๊ณ , ํšจ์œจ์ ์œผ๋กœ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ์–‘์˜ ๊ฐ€์ค‘์น˜์™€ ์Œ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์„ž์ธ ๊ทธ๋ž˜ํ”„:

  • ์–‘์˜ ๊ฐ€์ค‘์น˜์™€ ์Œ์˜ ๊ฐ€์ค‘์น˜๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” ๊ทธ๋ž˜ํ”„.
  • SPFA ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ๊ฐ„์„ ๋งŒ ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ, ๋‹ค์–‘ํ•œ ๊ฐ€์ค‘์น˜๊ฐ€ ์„ž์ธ ๊ทธ๋ž˜ํ”„์—์„œ๋„ ์ƒ๋Œ€์ ์œผ๋กœ ๋น ๋ฅด๊ฒŒ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4. ์Œ์˜ ์‚ฌ์ดํด์ด ์—†๋Š” ๊ทธ๋ž˜ํ”„:

  • ์Œ์˜ ์‚ฌ์ดํด์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ทธ๋ž˜ํ”„.
  • ์Œ์˜ ์‚ฌ์ดํด์ด ์—†๋Š” ๊ฒฝ์šฐ SPFA๋Š” ๋” ๋น ๋ฅด๊ฒŒ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ˆ˜๋ ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์Œ์˜ ์‚ฌ์ดํด์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์Œ์˜ ์‚ฌ์ดํด์ด ์—†๋Š” ๊ฒฝ์šฐ์— ๋” ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
๋ฐ˜์‘ํ˜•