Algorithms

[์ตœ๋‹จ๊ฒฝ๋กœ] ๋‹ค์ต์ŠคํŠธ๋ผ | ๋ฐฑ์ค€ 1753๋ฒˆ | python

galong 2024. 7. 7. 12:20

๐ŸŒŸ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ž€?

ํ•˜๋‚˜์˜ ์‹œ์ž‘ ์ •์ ์—์„œ ๋‹ค๋ฅด์ •์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 
์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋ผ๊ณ ๋„ ๋ถˆ๋ฆฐ๋‹ค! 

 

โš’๏ธ Dijkstra์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทธ๋ฆผ์—์„œ ์ตœ๋‹จ๊ฒฝ๋กœ๋ฅผ ๊ณ„์‚ฐํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

 

  1. ๊ฐ ๋‹จ๊ณ„์—์„œ S์•ˆ์— ์žˆ์ง€ ์•Š์€ ์ •์  ์ค‘์—์„œ ๊ฐ€์žฅ distance๊ฐ’์ด ์ž‘์€ ์ •์ ์„ S์— ์ถ”๊ฐ€ํ•œ๋‹ค.
  2. ์ •์  W๋ฅผ ๊ฑฐ์ณ์„œ ์ •์  u๋กœ ๊ฐ€๋Š” ๊ฐ€์ƒ์ ์ธ ๋” ์งง์€ ๊ฒฝ๋กœ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž!
    ๊ทธ๋Ÿฌ๋ฉด ์ •์  v์—์„œ ์ •์  u๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๋Š” v->w->u (๊ฒฝ๋กœ2 + ๊ฒฝ๋กœ3) ๊ฑฐ๋ฆฌ๊ฐ€ ๋œ๋‹ค.
  3. ๊ทธ๋Ÿฌ๋‚˜ ๊ฒฝ๋กœ 2๋Š” ๊ฒฝ๋กœ 1๋ณด๋‹ค ํ•ญ์ƒ ๊ธธ ์ˆ˜ ๋ฐ–์— ์—†๋‹ค. ํ˜„์žฌ distance ๊ฐ’์ด ๊ฐ€์žฅ ์ž‘์€ ์ •์ ์€ u์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. => ๊ฑฐ๋ฆฌ1 < ๊ฑฐ๋ฆฌ2 + ๊ฑฐ๋ฆฌ3

 

์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„  3๊ฐ€์ง€๋ฅผ ๊ณ ๋ คํ•ด์•ผํ•œ๋‹ค. 

  • direction
  • visited
  • queue
  • distance

โœ”๏ธ direction

๊ฐ ๋…ธ๋“œ์˜ ์ธ์ ‘ ๋…ธ๋“œ ๋ฒˆํ˜ธ์™€ ๊ฑฐ๋ฆฌ๊ฐ€ ์ €์žฅ๋˜์–ด์žˆ๋Š” ๋ฆฌ์ŠคํŠธ

 

โœ”๏ธ visited

๋…ธ๋“œ ๋ฐฉ๋ฌธ ์—ฌ๋ถ€

 

โœ”๏ธ queue

1. ์šฐ์„ ์ˆœ์œ„ ํ์—์„œ ๋…ธ๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ
2. ํ˜„์žฌ ์„ ํƒ๋œ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ ์ ์ด ์žˆ๋Š”์ง€ ํ™•์ธ
3. ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ ๋…ธ๋“œ๋กœ ์—…๋ฐ์ดํŠธ
4. for ํ˜„์žฌ ๋…ธ๋“œ์˜ ์ธ์ ‘ ๋…ธ๋“œ ๋งŒํผ
    4-1. ์ธ์ ‘ ๋…ธ๋“œ์˜ distance > ํ˜„์žฌ ๋…ธ๋“œ์˜ distance + ์ธ์ ‘ ๋…ธ๋“œ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ ์ด๋ฉด
    4-2. ์ธ์ ‘ ๋…ธ๋“œ์˜ distance ๊ฐ’ ๋ณ€๊ฒฝ
    4-3. queue์— ์ธ์ ‘ ๋…ธ๋“œ ์ถ”๊ฐ€

 

โœ”๏ธ distance

์‹œ์ž‘์ ์œผ๋กœ๋ถ€ํ„ฐ ๊ฐ ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ์ €์žฅ ๋ฐฐ์—ด

 


๐Ÿ‘พ ์ตœ๋‹จ๊ฒฝ๋กœ - ๋ฐฑ์ค€ 1753๋ฒˆ

https://www.acmicpc.net/problem/1753

์˜ˆ์ œ ์ž…๋ ฅ1

5 6
1
5 1 1
1 2 2
1 3 3
2 3 4
2 4 5
3 4 6

์˜ˆ์ œ ์ถœ๋ ฅ1

0
2
3
7
INF

 

๐Ÿ“ํ’€์ด โญ๏ธ

 

์ดˆ๊ธฐ ์„ค์ •

1. visited ์ดˆ๊ธฐํ™”
2. ๊ฐ ๋…ธ๋“œ์˜ distance๋Š” ์ตœ๋Œ€๋กœ 

 

distance

[1] [2] [3] [4] [5]
0

 

direction = [[] for _ in range(V + 1)]
visited = [False] * (V + 1)
queue = PriorityQueue()
distance = [sys.maxsize] * (V + 1)

 

direction ๋ฆฌ์ŠคํŠธ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ €์žฅํ•œ๋‹ค.

 

1 -> [2,2], [3,3]

2 -> [3,4], [4,5]
3 -> [4,6]
4
5 -> [1,1]

 

for _ in range(E):
    start, end, weight = map(int, input().split())

    direction[start].append([end, weight])
    
# ์ถœ๋ ฅ 
# direction [[], [[2, 2], [3, 3]], [[3, 4], [4, 5]], [[4, 6]], [], [[1, 1]]]

 

๋‹ค์ต์ŠคํŠธ๋ผ ์ˆ˜ํ–‰

1๏ธโƒฃ K๋ฅผ ์‹œ์ž‘์ ์œผ๋กœ ์„ค์ •

queue.put((0, K)) 
distance[K] = 0

 

2๏ธโƒฃ queue๊ฐ€ ๋นŒ ๋•Œ๊นŒ์ง€

(1) ์šฐ์„ ์ˆœ์œ„ ํ์—์„œ ๋…ธ๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ
(2) ํ˜„์žฌ ์„ ํƒ๋œ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ ์ ์ด ์žˆ๋Š”์ง€ ํ™•์ธ
(3) ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ ๋…ธ๋“œ๋กœ ์—…๋ฐ์ดํŠธ
(4) for ํ˜„์žฌ ๋…ธ๋“œ์˜ ์ธ์ ‘ ๋…ธ๋“œ ๋งŒํผ
      (4.1) ์ธ์ ‘ ๋…ธ๋“œ์˜ distance > ํ˜„์žฌ ๋…ธ๋“œ์˜ distance + ์ธ์ ‘ ๋…ธ๋“œ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ ์ด๋ฉด
      (4.2) ์ธ์ ‘ ๋…ธ๋“œ์˜ distance ๊ฐ’ ๋ณ€๊ฒฝ
      (4.3) queue์— ์ธ์ ‘ ๋…ธ๋“œ ์ถ”๊ฐ€

 

 

1๋ฒˆ ๋…ธ๋“œ ์„ ํƒ

 

visited

[0]
1

 

distance

[1] [2] [3] [4] [5]
0 2 3

 

queue

[0] [1]
2 3

 

2๋ฒˆ ๋…ธ๋“œ ์„ ํƒ

visited

[0] [1]
1 2

 

distance

[1] [2] [3] [4] [5]
0 2 3 7

 

queue

[0] [1]
3 4

 

 

3๋ฒˆ ๋…ธ๋“œ ์„ ํƒ

 

visited

[0] [1] [2] [3]
1 2 3 4

 

distance

๋…ธ๋“œ4 ๊ฐ™์€ ๊ฒฝ์šฐ, ๊ธฐ์กด์— ์žˆ๋Š” ๊ฐ’์ด ์‹ ๊ทœ ๊ฐ’๋ณด๋‹ค ์ž‘์„ ๊ฒฝ์šฐ ๊ฐฑ์‹ ํ•˜์ง€ ์•Š์Œ! (7 < 3+6)

[1] [2] [3] [4] [5]
0 2 3 7

 

queue

[0]
4

 

while queue.qsize() > 0:
    current = queue.get()

    current_node = current[1]

    if visited[current_node]:
        continue

    visited[current_node] = True

    for tmp in direction[current_node]:
        next = tmp[0]
        value = tmp[1]

        if visited[next]:
            continue

        if distance[next] > distance[current_node] + value:  # ๋” ์งง์€ distance ๊ฐฑ์‹ 
            distance[next] = distance[current_node] + value

            queue.put((distance[next], next))

 

๐Ÿ“์ „์ฒด ์ฝ”๋“œ

# ๋‹ค์ต์ŠคํŠธ๋ผ
import sys
from queue import PriorityQueue
input = sys.stdin.readline

# V(์ •์ ์˜ ๊ฐœ์ˆ˜), E(๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜)
V, E = map(int, input().split())
# K (์‹œ์ž‘ ์ •์ )
K = int(input())

direction = [[] for _ in range(V + 1)]
visited = [False] * (V + 1)
queue = PriorityQueue()
distance = [sys.maxsize] * (V + 1)

for _ in range(E):
    start, end, weight = map(int, input().split())

    direction[start].append([end, weight])

# print("direction", direction)

queue.put((0, K))  # K๋ฅผ ์‹œ์ž‘์ ์œผ๋กœ (๊ฑฐ๋ฆฌ, ์ถœ๋ฐœ)
distance[K] = 0

while queue.qsize() > 0:
    current = queue.get()

    current_node = current[1]

    if visited[current_node]:
        continue

    visited[current_node] = True

    for tmp in direction[current_node]:
        next = tmp[0]
        value = tmp[1]

        if visited[next]:
            continue

        if distance[next] > distance[current_node] + value:  # ๋” ์งง์€ distance ๊ฐฑ์‹ 
            distance[next] = distance[current_node] + value

            queue.put((distance[next], next))

for i in range(1, V + 1):
    if visited[i]:
        print(distance[i])
    else:
        print("INF")