๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
ProgramSolve/Baekjoon

[BOJ] 1753๋ฒˆ - ์ตœ๋‹จ๊ฒฝ๋กœ(Python) + Dijkstra Algorithm

by SooooooooS 2023. 9. 4.
728x90

๐Ÿ—’๏ธ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Dijkstra Algorithm)

  • ๋ชจ์„œ๋ฆฌ ๋˜๋Š” ์ •์ ์— ๊ฐ€์ค‘์น˜๊ฐ€ ๋ถ€์—ฌ๋œ ๊ทธ๋ž˜ํ”„์—์„œ ๋‘ ์ •์  ์‚ฌ์ด์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • ๊ฐ€์ค‘์น˜๊ฐ€ ์—†๋Š” ๊ทธ๋ž˜ํ”„์—์„œ์˜ ์ตœ๋‹จ๊ฒฝ๋กœ๋Š” BFS๋ฅผ ์‚ฌ์šฉ!
  • ์–ด๋–ค ์‹œ์ž‘์  s๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ๊ทธ ์ •์ ์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ๋‹ค๋ฅธ ๋ชจ๋“  ์ •์ ์œผ๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š”๋‹ค.
  • ๋‹จ, ์Œ์ˆ˜์ธ ๊ฐ€์ค‘์น˜๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—๋งŒ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

์Œ์ˆ˜์˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ

์‹ค์ œ ์ตœ๋‹จ ๊ฒฝ๋กœ๋Š” ์šฐ๋ฆฌ์ง‘์—์„œ ์˜†์ง‘์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ, ์šฐ๋ฆฌ์ง‘์—์„œ ์€ํ–‰์„ ๊ฑฐ์ณ ๊ฐ€๋Š” ๊ฒƒ์ด ๋น„์šฉ์ƒ ์ด๋“์ด ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ฆ‰, ๊ฐ’์ด ์Œ์ˆ˜์ธ ๋ชจ์„œ๋ฆฌ๊ฐ€ ์žˆ์œผ๋ฉด ๊ฒฝ๋กœ๋ฅผ ๋งŒ๋“ค์–ด๊ฐ€๋Š” ๋„์ค‘์— ์•„์ฃผ ์ž‘์€ ์Œ์ˆ˜ ๊ฐ’์„ ๊ฐ€์ง€๋Š” ๋ชจ์„œ๋ฆฌ๊ฐ€ ์žˆ์–ด์„œ ์ด๋ฏธ ํŠธ๋ฆฌ์— ๋“ค์–ด์žˆ๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ์™€ ์ „ํ˜€ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋™์ž‘ ๊ณผ์ •(๊ฐ„์„  ์™„ํ™” ๊ณผ์ •)

1. ๋ชจ๋“  ๊ผญ์ง“์ ์„ ๋ฏธ๋ฐฉ๋ฌธ ์ƒํƒœ๋กœ ํ‘œ์‹œ : visited
2. ์ดˆ๊ธฐ์ ์„ 0์œผ๋กœ, ๋‹ค๋ฅธ ๋ชจ๋“  ๊ผญ์ง“์ ์„ ๋ฌดํ•œ๋Œ€๋กœ ์„ค์ • : distance
3. ํ˜„์žฌ ๊ผญ์ง“์  k์—์„œ ๋ฏธ๋ฐฉ๋ฌธ ์ธ์ ‘ ๊ผญ์ง“์  v์„ ์ฐพ์•„ ๊ทธ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐ
    : distance[k] + weight(k์™€ v ์‚ฌ์ด์˜ ๊ฐ€์ค‘์น˜)
    ๋งŒ์•ฝ ๊ณ„์‚ฐํ•œ ๊ฑฐ๋ฆฌ๊ฐ€ ํ˜„์žฌ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๊ฐ’๋ณด๋‹ค ์ž‘์œผ๋ฉด ๋ณ€๊ฒฝ
    : if (distance[k] + weight < distance[v]) → distance[v] = distance[k] + weight
4. ๋งŒ์•ฝ ํ˜„์žฌ ๊ผญ์ง“์ ์— ์ธ์ ‘ํ•œ ๋ชจ๋“  ๋ฏธ๋ฐฉ๋ฌธ ๊ผญ์ง“์ ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•œ ๊ฒฝ์šฐ → visited[k] = True

→ ๋‘ ๊ผญ์ง“์  ์‚ฌ์ด์˜ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๊ฒฝ์šฐ
     : ๋„์ฐฉ์ ์ด ๋ฐฉ๋ฌธํ•œ ์ƒํƒœ๋กœ ํ‘œ์‹œ๋˜๋ฉด ๋ฉˆ์ถ”๊ณ  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ข…๋ฃŒํ•œ๋‹ค.
→ ์™„์ „ ์ˆœํšŒ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๊ฒฝ์šฐ
     : if (๋ฏธ๋ฐฉ๋ฌธ ์ง‘ํ•ฉ์— ์žˆ๋Š” ๊ผญ์ง“์ ๋“ค์˜ distance ์ค‘ ์ตœ์†Ÿ๊ฐ’์ด ๋ฌดํ•œ๋Œ€)
            ์ถœ๋ฐœ์ ๊ณผ ๋ฏธ๋ฐฉ๋ฌธ ์ง‘ํ•ฉ ์‚ฌ์ด์— ์—ฐ๊ฒฐ์ด ์—†๋Š” ๊ฒฝ์šฐ์ด๋ฏ€๋กœ ๋ฉˆ์ถ”๊ณ  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ข…๋ฃŒ
       else
            distance๊ฐ€ ๊ฐ€์žฅ ์ž‘์€ ๋‹ค์Œ ๋ฏธ๋ฐฉ๋ฌธ ๊ผญ์ง“์ ์„ "ํ˜„์žฌ ์œ„์น˜"๋กœ ์„ ํƒํ•˜๊ณ  3๋‹จ๊ณ„๋กœ ๋˜๋Œ์•„๊ฐ„๋‹ค.

์ฆ‰, ๋‹ค์Œ ์ •์ ์„ ์„ ํƒํ•˜๋Š” ๊ธฐ์ค€์€ ์‹œ์ž‘ ์ •์ ์—์„œ ๋ถ€ํ„ฐ ๊ฒฝ๋กœ(distance)๊ฐ€ ๊ฐ€์žฅ ์งง์€ ์ •์ ์ด๋‹ค!

์ด๋ฅผ ์„ ํƒํ•  ๋ฐฉ๋ฒ•์€ ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉ๊ฑฐ๋‚˜ ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด์— ๋Œ€ํ•œ ์˜ˆ์‹œ๋Š” ์•„๋ž˜์˜ ํ’€์ด์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

[์ฐธ๊ณ ]

https://ko.wikipedia.org/wiki/๋‹ค์ต์ŠคํŠธ๋ผ_์•Œ๊ณ ๋ฆฌ์ฆ˜

https://code-lab1.tistory.com/29

https://justkode.kr/algorithm/python-dijkstra/


๐Ÿ› ๏ธ ๋ฌธ์ œ ๐Ÿ› ๏ธ


๐Ÿ€ ํ’€์ด ๐Ÿ€

1. ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•œ ํ’€์ด

import sys

v, e = map(int, sys.stdin.readline().split())
k = int(sys.stdin.readline()) # ์‹œ์ž‘ ์ •์ 
graph = [[] for _  in range(v+1)]

for _ in range(e) :
    a, b, w = map(int, sys.stdin.readline().split())
    graph[a].append((b, w))

def dijkstra(graph, s, v) :
    visited = [False] * (v+1)
    distance = [sys.maxsize] * (v+1)
    
    distance[s] = 0
    current = s
    
    for _ in range(v) :
        visited[current] = True
        for vertex, weight in graph[current] :
            distance[vertex] = min(distance[vertex], distance[current] + weight)

        # distance๊ฐ€ ๊ฐ€์žฅ ์งง์€ ์ •์  ์„ ํƒ! - ๋ฐ˜๋ณต๋ฌธ ์ด์šฉ
        min_dist = sys.maxsize
        for i in range(1, v+1) :
            if visited[i] == False and min_dist > distance[i] :
                current = i
                min_dist = distance[i]
    
    for i in range(1, v+1) :
        if distance[i] == sys.maxsize :
            print("INF")
        else :
            print(distance[i])

dijkstra(graph, k, v)

์œ„์—์„œ ์ •๋ฆฌํ•œ ๊ฐ„์„  ์™„ํ™” ๊ณผ์ •์„ ํ† ๋Œ€๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ์ด๋‹ค.

์ •๋‹ต์„ ๋„์ถœํ•˜๊ธด ํ–ˆ์ง€๋งŒ ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๋ชจ๋“  ์ •์ ์˜ distance๋ฅผ ํ™•์ธํ•˜๊ณ  ๊ทธ ์ค‘ ๊ฐ€์žฅ ์งง์€ ์ •์ ์„ ์„ ํƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(V^2)์ด๋‹ค.

 

2. ์šฐ์„ ์ˆœ์œ„ ํ๋ฅผ ์‚ฌ์šฉํ•œ ํ’€์ด

import sys
import heapq

v, e = map(int, sys.stdin.readline().split())
k = int(sys.stdin.readline()) # ์‹œ์ž‘ ์ •์ 
graph = [[] for _  in range(v+1)]

for _ in range(e) :
    a, b, w = map(int, sys.stdin.readline().split())
    graph[a].append((b, w))

def dijkstra(graph, s, v) :
    distance = [sys.maxsize] * (v+1)
    queue = []
    
    distance[s] = 0
    heapq.heappush(queue, [distance[s], s])
    
    while queue :
        # distance๊ฐ€ ๊ฐ€์žฅ ์งง์€ ๊ฒƒ๋ถ€ํ„ฐ pop - ์šฐ์„ ์ˆœ์œ„ ํ ์‚ฌ์šฉ
        dist, vertext = heapq.heappop(queue)
        
        if distance[vertext] >= dist :
            for nv, w in graph[vertext] :
                if distance[nv] > dist + w :
                    distance[nv] = dist + w
                    heapq.heappush(queue, [distance[nv], nv])
    
    for i in range(1, v+1) :
        if distance[i] == sys.maxsize :
            print("INF")
        else :
            print(distance[i])

dijkstra(graph, k, v)

์ด ์ฝ”๋“œ๋Š” ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ์ž๋ฃŒ๊ตฌ์กฐ ์ค‘ heap์„ ์‚ฌ์šฉํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค.

 

๋ชจ๋“  ๊ฐ„์„ ์€ ํ•œ ๋ฒˆ์”ฉ ๊ฒ€์‚ฌ๋˜๋ฏ€๋กœ ์ „์ฒด O(|E|)์˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฐ๋‹ค.
์šฐ์„ ์ˆœ์œ„ ํ๊ฐ€ ๊ฐ€์žฅ ์ปค์ง€๋Š” ์ตœ์•…์˜ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๊ทธ๋ž˜ํ”„์˜ ๋ชจ๋“  ๊ฐ„์„ ์ด ๊ฒ€์‚ฌ๋  ๋•Œ๋งˆ๋‹ค distance๊ฐ€ ๊ฐฑ์‹ ๋˜๊ณ  ์šฐ์„ ์ˆœ์œ„ ํ์— ์ •์ ์˜ ๋ฒˆํ˜ธ๊ฐ€ ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ์œผ๋กœ, ์šฐ์„ ์ˆœ์œ„ ํ์— ์ถ”๊ฐ€๋˜๋Š” ์›์†Œ์˜ ์ˆ˜๋Š” ์ตœ๋Œ€ E๊ฐœ์ด๊ณ , ์‚ฝ์ž…์—ฐ์‚ฐ์ด ์ผ์–ด๋‚œ๋‹ค๋Š” ์ ์—์„œ ์ „์ฒด ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(|E||log|E|)๊ฐ€ ๋จ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
๋Œ€๊ฐœ์˜ ๊ฒฝ์šฐ ๊ทธ๋ž˜ํ”„์—์„œ |E| < |V|^2 ์ด๊ธฐ ๋•Œ๋ฌธ์— O(log|E|)=O(log|V|)๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(|E||log|V|)๊ฐ€ ๋œ๋‹ค.

 

[์ฐธ๊ณ ]

https://ds-jungsoo.tistory.com/7

728x90