๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ (Dijkstra Algorithm)
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ํ ์ ์ ์์ ๋ชจ๋ ์ ์ ๊น์ง์ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ๊ฐ ๊ตฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ ํ์ ๊ณผ์
[step 1] ์ถ๋ฐ ๋ ธ๋์ ๋์ฐฉ ๋ ธ๋๋ฅผ ์ค์
[step 2] ์ถ๋ฐ ๋ ธ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ฐ ๋ ธ๋์ ์ต์ ๋น์ฉ์ ์ ์ฅ ( ๊ฐ ์ ์๋ค๋ฉด INF๋ก ์ค์ )
[step 3] ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋ ์ค์์ ๋น์ฉ์ด ๊ฐ์ฅ ์ ์ ๋ ธ๋๋ฅผ ์ ํ
[step 4] ํด๋น ๋ ธ๋๋ฅผ ๊ฑฐ์ณ์ ํน์ ๋ ธ๋๋ก ๊ฐ๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํ์ฌ ์ต์ ๋น์ฉ ๊ฐฑ์
[step 5] 3,4 ๊ณผ์ ์ ๋ฐ๋ณต
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ ํ์ ์์
์ด์ฐจ์ ๋ฐฐ์ด ํํ๋ก ๊ทธ๋ํ๋ฅผ ์ฒ๋ฆฌ
์ถ๋ฐ/๋์ฐฉ | 1 | 2 | 3 | 4 | 5 | 6 |
1 | 0 | 2 | 5 | 1 | INF | INF |
2 | INF | 0 | 3 | 2 | INF | INF |
3 | INF | 3 | 0 | INF | INF | 5 |
4 | INF | INF | 3 | 0 | 1 | INF |
5 | INF | INF | 1 | INF | 0 | 2 |
6 | INF | INF | INF | INF | INF | 0 |
์ถ๋ฐ ๋ ธ๋๋ฅผ 1, ๋์ฐฉ ๋ ธ๋๋ฅผ 6์ผ๋ก ์ค์ ํ๊ณ ์ต์ ๋น์ฉ ํ ์ด๋ธ์ ์ด๊ธฐํ
0 | 2 | 5 | 1 | INF | INF |
ํ์ฌ ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋ ์ค ๋น์ฉ์ด ์ต์์ธ 4๋ฒ ๋ ธ๋ ์ ํ
4๋ฒ ๋ ธ๋๋ฅผ ๊ฑฐ์ณ์ ๊ฐ ์ ์๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํ์ฌ ์ต์ ๋น์ฉ ๋ฐฐ์ด์ ๊ฐฑ์
0 | 2 | min(5, 1+3) = 4 | 1 | min(INF, 1+1) = 2 | INF |
๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋์ค ๋น์ฉ์ด ์ต์์ธ 2๋ฒ ๋ ธ๋ ์ ํ( ๋น์ฉ์ด ๊ฐ์ ๊ฒฝ์ฐ ์์ ์ธ๋ฑ์ค ์ ํ)
2๋ฒ ๋ ธ๋๋ฅผ ๊ฑฐ์ณ ๊ฐ ์ ์๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํ์ฌ ์ต์ ๋น์ฉ ๋ฐฐ์ด ๊ฐฑ์
0 | 2 | 4 | 1 | 2 | INF |
๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋์ค ๋น์ฉ์ด ์ต์์ธ 5๋ฒ ๋ ธ๋ ์ ํ
5๋ฒ ๋ ธ๋๋ฅผ ๊ฑฐ์ณ๊ฐ ์ ์๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํ์ฌ ์ต์ ๋น์ฉ ๋ฐฐ์ด ๊ฐฑ์
0 | 2 | min(4, 2+1) = 3 | 1 | 2 | min(INF, 2+2) = 4 |
๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋ ์ค ๋น์ฉ์ด ์ต์์ธ 3๋ฒ ๋ ธ๋ ์ ํ
3๋ฒ ๋ ธ๋๋ฅผ ๊ฑฐ์ณ๊ฐ ์ ์๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํ์ฌ ์ต์ ๋น์ฉ ๋ฐฐ์ด ๊ฐฑ์
0 | 2 | 3 | 1 | 2 | min(4, 3+5) = 4 |
์ต์ข ์ ์ผ๋ก 1๋ฒ์์ 6๋ฒ๊น์ง ๊ฐ๋๋ฐ 1 - 4 - 5 - 6 ๊ฒฝ๋ก๋ฅผ ๊ฑฐ์น๊ณ , ์ต์ ๊ฑฐ๋ฆฌ๋ 4์ด๋ค.
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ ์ฝ๋ - 1
import sys
INF = (1e9)
n = int(input()) # ๋
ธ๋์ ๊ฐฏ์ n
m = int(input()) # ๊ฐ์ ์ ๊ฐฏ์ m
start = int(input())
# ๊ทธ๋ํ ์ด๊ธฐํ
graph = [[] for i in range(n + 1)]
# ๋ฐฉ๋ฌธ ์ฌ๋ถ๋ฅผ ๊ธฐ๋ก
visited = [False]*(n+1)
# ์ต๋จ ๊ฑฐ๋ฆฌ ๊ธฐ๋ก
distance = [INF] * (n+1)
for _ in range(m):
#a์์ b๋ก ๊ฐ๋ ๋น์ฉ c
a,b,c = map(int,sys.stdin.readline().rstrip().split())
graph[a].append((b,c))
# cost๊ฐ ์ต์์ธ ๋
ธ๋ ์ฐพ๊ธฐ
def get_smallest():
min_value = INF
index = 0
for i in range(1,n+1):
if distance[i] < min_value and not visited[i]:
min_value = distance[i]
index = i
return index
def dijkstra(start):
# ์์ ๋
ธ๋์ ๊ฑฐ๋ฆฌ๋ฅผ 0์ผ๋ก ์ค์ ๋ฐ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ
distance[start] = 0
visited[start] = True
# ์์๋
ธ๋์ ์ฐ๊ฒฐ๋ ๋
ธ๋์ ๊ฑฐ๋ฆฌ ์ค์
for j in graph[start]:
distance[j[0]] = j[1]
for _ in range(n-1):
# ํ์ฌ cost๊ฐ ์ต์์ธ ๋
ธ๋
now = get_smallest()
# ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ
visited[now] = True
# ํ์ฌ ๋ฐฉ๋ฌธ์ค์ธ ๋
ธ๋์ ๋ํด ๊ฑฐ๋ฆฌ ๊ฐฑ์
for j in graph[now]:
cost = distance[now] + j[1]
if cost < distance[j[0]]:
distance[j[0]] = cost
dijkstra(start)
for i in range(1,n+1):
print(-1 if distance[i] == INF else distance[i], end = " ")
๋ค์ต์คํธ๋ผ 1์ ์๊ฐ ๋ณต์ก๋
- get_smallest()
- ๋ฐ๋ณต๋ฌธ์ ํตํด ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋์ค cost๊ฐ ์ต์์ธ ๋ ธ๋๋ฅผ ์ฐพ๋๋ค. ์ด ํจ์๋ ๋ค์ต์คํธ๋ผ ํจ์์์ n-1 ๋ฒ ๋ฐ๋ณต๋๋ฏ๋ก ์๊ฐ ๋ณต์ก๋๋ O(n^2)์ด๋ค.
- dijkstra()
- ๋ชจ๋ ๋ ธ๋์ ๋ํด ์ด๊ธฐ ๊ฑฐ๋ฆฌ๋ฅผ ์ค์ ํ๋ ์๊ฐ ๋ณต์ก๋๋ O(m)
- ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฒด ์๊ฐ๋ณต์ก๋๋ O(n^2 + m) ์ด๋ฏ๋ก ์ต์ข ์ ์ธ ์๊ฐ ๋ณต์ก๋๋ O(n^2)์ด๋ค.
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ ์ฝ๋ - 2 ( ์ฐ์ ์์ ํ ์ฌ์ฉ)
๋๋ฒ์งธ ๋ฐฉ๋ฒ์ heap ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ค.
2024.08.07 - [๐์ฝ๋ฉํ ์คํธ/Python] - [Python] heapq ๋ผ์ด๋ธ๋ฌ๋ฆฌ
[Python] heapq ๋ผ์ด๋ธ๋ฌ๋ฆฌ
ํํ(heapq)๋ ํ์ด์ฌ ํ์ค๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ ๊ณตํ๋ ๋ชจ๋๋ก Heap ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ง์ํ๋ค. ์์ ์ด์งํธ๋ฆฌ ํํ๋ฅผ ํ๊ณ ์์ผ๋ฉฐ, ์ต์๊ฐ๊ณผ ์ต๋๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ์ ์ ์๋ค . ํ์ด์ฌ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ต์ํ(m
yobi-devlog.tistory.com
import sys
import heapq
INF = int(1e9)
n = int(input()) # ๋
ธ๋์ ๊ฐฏ์ n
m = int(input()) # ๊ฐ์ ์ ๊ฐฏ์ m
start = int(input()) # ์์ ์ง์
graph = [[] for _ in range(n+1)]
distance = [INF] * (n+1)
for _ in range(m):
# a์์ b๋ก ๊ฐ๋ ๋น์ฉ c
a,b,c = map(int,sys.stdin.readline().rstrip().split())
graph[a].append((b,c))
def dijkstra(start):
queue = []
# ํ์ ์์ ์์น๋ฅผ ์ฝ์
heapq.heappush(queue, (0, start))
distance[start] = 0
# ํ์ ๋
ธ๋๊ฐ ์๋ ๋์ ์คํ
while queue:
# ํ์์ cost๊ฐ ์ต์์ธ ๋
ธ๋ pop
dist, now = heapq.heappop(queue)
# ํด๋น ๋
ธ๋์ cost๊ฐ distance์ ๊ธฐ๋ก๋ ๊ฐ๋ณด๋ค ํฌ๋ค๋ฉด ํจ์ค
if distance[now] < dist:
continue
# distance ๊ฐฑ์
for i in graph[now]:
cost = dist + i[1]
if cost < distance[i[0]]:
distance[i[0]] = cost
heapq.heappush(queue, (cost, i[0]))
dijkstra(start)
for i in range(1, n+1):
print(-1 if distance[i] == INF else distance[i], end = " ")
๋ค์ต์คํธ๋ผ 2์ ์๊ฐ ๋ณต์ก๋
- ์ฐ์ ์์ ํ๋ฅผ ์ฌ์ฉํ์ฌ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ง ๋ ธ๋๋ฅผ ์ ํํ๋ค.
- ์ฐ์ ์์ ํ์์ ์์๋ฅผ ์ฝ์ ํ๊ฑฐ๋ ์ ๊ฑฐํ๋ ๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ O(log n) ์ด๋ค.
- ๋ค์ต์คํธ๋ผ ๋ฉ์ธ ๋ฃจํ์์ ํ์ ๋ ธ๋๊ฐ ์๋ ๋์ ๊ฐ ๋ ธ๋์ ๋ํด ์ธ์ ํ ๋ชจ๋ ๋ ธ๋๋ฅผ ํ์ํ๋ค.
- ๊ฐ ๊ฐ์ ์ ๋ฐ๋ผ ์ต๋จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํ๊ณ ์๋ก์ด ์ต๋จ ๊ฑฐ๋ฆฌ๊ฐ ๋ฐ์ํ ๋ ๋ง๋ค ํ์ ์ฝ์ ํ๋ค.
- ๋ชจ๋ ๊ฐ์ ์ ๋ํด ์ด๋ฃจ์ด์ง๋ฏ๋ก ๊ฐ์ ์ ์ m์ ๋น๋กํ ์๊ฐ์ด ์์๋๋ค.
- ์ต์ข ์ ์ธ ์๊ฐ ๋ณต์ก๋๋ O(m log n)์ด ์์๋๋ค.
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์ ์ฅ๋จ์
- ์ฅ์
- ๋จ์ผ ์์์ ์์ ๋ชจ๋ ๋ ธ๋๋ก์ ์ต๋จ ๊ฒฝ๋ก ํ์ ๊ฐ๋ฅ
- ์ฐ์ ์์ ํ๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์จ์ ์ธ ํ์ ๊ฐ๋ฅ
- ๋จ์
- ์์ ๊ฐ์ค์น๊ฐ ์๋ ๊ทธ๋ํ์์๋ ์ฌ์ฉ ๋ถ๊ฐ๋ฅ (๋ฒจ๋ง-ํฌ๋ ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉ ๋์)
- ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ํ์ํ์ง ์๋๋ค. (๋ณต์์ ๊ฒฝ๋ก ์ ๊ณต x)
ํจ๊ป ๋ณด๋ฉด ์ข์ ๋ฌธ์
1753. ์ต๋จ ๊ฒฝ๋ก
'๐ค์๊ณ ๋ฆฌ์ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๊ณ ๋ฆฌ์ฆ] ํฌ๋ฃจ์ค์นผ ์๊ณ ๋ฆฌ์ฆ (Kruskal Algorithm) (0) | 2024.08.29 |
---|---|
[์๊ณ ๋ฆฌ์ฆ] BFS (๋๋น ์ฐ์ ํ์) (0) | 2024.08.20 |
[์๊ณ ๋ฆฌ์ฆ] DFS (๊น์ด ์ฐ์ ํ์) (0) | 2024.08.20 |
[์๊ณ ๋ฆฌ์ฆ] ๋ฐฑํธ๋ํน (Backtracking) (0) | 2024.08.20 |
[์๊ณ ๋ฆฌ์ฆ] ํ๋ก์ด๋ ์์ ์๊ณ ๋ฆฌ์ฆ (Floyd - Warshall Algorithm) (0) | 2024.08.17 |