๐๏ธ ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ (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|)๊ฐ ๋๋ค.
[์ฐธ๊ณ ]
'ProgramSolve > Baekjoon' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[BOJ] 15657๋ฒ - N๊ณผM(8) (Python) (1) | 2023.10.05 |
---|---|
[BOJ] 1911๋ฒ - ํ๊ธธ ๋ณด์ํ๊ธฐ (Python) (0) | 2023.09.07 |
[BOJ] 13549๋ฒ - ์จ๋ฐ๊ผญ์ง3 (Python) (0) | 2023.09.05 |
[BOJ] 6064๋ฒ - ์นด์ ๋ฌ๋ ฅ(JAVA) (0) | 2023.03.27 |
[BOJ] 2667๋ฒ - ๋จ์ง๋ฒํธ๋ถ์ด๊ธฐ(JAVA) (0) | 2023.03.23 |