
크래프톤 정글 캠퍼스에서 캐리비안베이로 가는 제일 빠른 길은??
실내 교육장에만 있다 보니 웃통 까고 선탠하고 싶습니다.
농담입니다. 예쁜 래시가드 입겠습니다.
좌우지간, 최단 경로 알고리즘에 대해 알아봅시다.
가장 짧은 경로를 찾는 알고리즘

최단 경로: 이동한 간선의 가중치 합이 최저값인 경로
⚠️ 보통 간선의 가중치 합을 거리라고 합니다.
| 알고리즘 | 언제? | 시간 복잡도 (노드수 간선수 ) |
|---|---|---|
| BFS | 가중치가 명시되지 않은 경우 한 노드 -> 모든 노드 간 거리 | |
| 다익스트라 | 0 이상의 가중치가 명시된 경우 한 노드 -> 모든 노드 간 거리 | |
| 플로이드 워셜 | 모든 노드 -> 모든 노드 간 거리 |
⚠️ 음의 가중치를 가진 간선이 있는 경우, 벨만-포드 알고리즘을 사용합니다. 이 글에선 다루지 않습니다.

(3) 방문하지 않은 노드 중, 최단 거리가 가장 짧은 노드 방문
(4) 현재 노드와 인접한 노드들 확인
(현재 노드의 최단거리 테이블 값) + (현재 노드와 인접 노드의 간선 가중치)
(4 -> 5)까지의 거리 2 -> 1로 수정합니다. 즉 합산 거리는 3이 아니라 2가 되겠죠




INF = float('inf') # 무한의 값
# 각 노드와 연결된 노드를 인접 리스트로 관리
# (도착 노드, 비용)
graph = [
[],
[(2, 2), (4, 1)],
[(3, 3), (4, 2)],
[(2, 3), (6, 5)],
[(3, 3), (5, 1)],
[(3, 1), (6, 2)],
[]
]
N = len(graph) - 1
visited = [False] * (N + 1) # 방문 여부 확인
dist_table = [INF] * (N + 1) # 최단 거리 테이블
visited 리스트로 방문 여부 확인visited[i] = True일 시 i번노드 방문, 아닐 시 방문 Xfloat('inf') 로 무한 값 사용 가능# 방문하지 않은 노드 중, 가장 최단거리가 짧은 노드의 번호 반환
def shortest_node():
min_dist = INF
min_node = 0
for i in range(1, N + 1):
if dist_table[i] < min_dist and not visited[i]:
min_dist = dist_table[i]
min_node = i
return min_node
# 다익스트라 알고리즘
def djikstra(start):
dist_table[start] = 0 # 출발 노드의 최단거리는 0
# 각 노드에 대해서...
for _ in range(N):
i = shortest_node()
visited[i] = True
# 인접 노드의 거리 갱신
# j: 인접노드 번호, j_dist: 간선 비용
for j, j_dist in graph[i]:
cost = dist_table[i] + j_dist
if cost < dist_table[j]:
dist_table[j] = cost
dist_table 리스트의 모든 값을 탐색하여 최솟값을 구함dist_table[i] (출발 노드 -> i 노드) + j_dist (i 노드 -> 인접 j 노드)djikstra(1)
for i in range(1, N + 1):
if dist_table[i] == INF:
print("X")
else:
print(f"노드 {i} 최단거리: {dist[i]}")
# 노드 1 최단거리: 0
# 노드 2 최단거리: 2
# 노드 3 최단거리: 3
# 노드 4 최단거리: 1
# 노드 5 최단거리: 2
# 노드 6 최단거리: 4
shortest_node 함수로 현재 최단 거리의 노드를 선형 탐색할 때 shortest_node 함수가 실행되므로 (거리, 노드) 꼴의 튜플 삽입(0, 출발 노드) 삽입
(거리, 노드) 튜플을 우선순위 큐에 푸시dist[A] = 3인데 큐에서 (5, A)가 팝된 경우visited 배열이 필요 없음




제가 모르고 #6을 건너뛰고 #7로 적어 놨군요. 사진 하나가 빠진 건 아니니 걱정마십쇼.

import heapq
import sys
input = sys.stdin.readline
INF = float('inf')
# 각 노드와 연결된 노드를 인접 리스트로 관리
# (도착 노드, 비용)
graph = [
[],
[(2, 2), (4, 1)],
[(3, 3), (4, 2)],
[(2, 3), (6, 5)],
[(3, 3), (5, 1)],
[(3, 1), (6, 2)],
[]
]
N = 6
# 최단 거리 테이블
dist_table = [INF] * (N + 1)
visited 리스트가 없는 것 빼고 동일def djikstra(start):
queue = []
# 시작 노드를 큐에 삽입 및 거리 0으로 설정
heapq.heappush(queue, (0, start))
dist_table[start] = 0
while queue:
# 가장 최단 거리가 짧은 노드 i 꺼내기
i_dist, i = heapq.heappop(queue)
# 이미 더 짧은 거리로 방문한 경우 무시
if i_dist > dist_table[i]:
continue
# i의 인접 노드 j 확인
for j, j_dist in graph[i]:
# j: 인접 노드, j_dist: 간선 가중치
# 현재 노드를 거쳐, 인접 노드로 이동하는 거리
new_dist = i_dist + j_dist
# 거리가 더 짧으면 갱신
if new_dist < dist_table[j]:
dist_table[j] = new_dist
heapq.heappush(queue, (new_dist, j))
queue에 거리가 갱신될 때마다 (거리, 노드번호) 푸시dist_table[i][j] -> 노드 i부터 j까지 최단 거리dist_table[i][j] = min(dist_table[i][j], dist_table[i][k] + dist_table[k][j])
k를 거쳐 가는 경우를 고려하여 테이블을 갱신i, 도착 노드를 j라 할 때i -> k + k -> j 간 거리가 기존 i -> j 간 거리보다 가까우면 갱신



INF = float('inf')
# 그래프의 인접 행렬 표현
dist_table = [
[INF, 4, INF, 6],
[3, INF, 7, INF],
[5, INF, INF, 4],
[INF, INF, 2, INF]
]
N = 4
# 자기 자신과의 거리는 0
for i in range(N):
for j in range(N):
if i == j:
dist_table[i][j] = 0
# 플로이드 와셜 알고리즘 수행
for k in range(N): # 중간 노드
for i in range(N): # 출발 노드
for j in range(N): # 도착 노드
dist_table[i][j] = min(dist_table[i][j], dist_table[i][k] + dist_table[k][j])
k에 대해i -> k -> j의 경로가 기존 i -> j의 경로보다 짧으면 값을 갱신# 결과 출력
for i in range(N):
for j in range(N):
if dist_table[i][j] == INF:
print(f"{'X':4}", end = "")
else:
print(f"{dist_table[i][j]:4}", end="")
print()
# 0 4 8 6
# 3 0 7 9
# 5 9 0 4
# 7 11 2 0
import heapq
import sys
input = sys.stdin.readline
N = int(input())
M = int(input())
INF = float('inf')
graph = [[] for _ in range(N + 1)] # 인접리스트
dist_table = [INF] * (N + 1) # 거리 정보
# 인접 리스트 만들기: (노드, 가중치)
for _ in range(M):
a, b, dist = map(int, input().split())
graph[a].append((b, dist))
chulbal, dochak = map(int, input().split())
# 다익스트라 알고리즘
def djikstra(chulbal, dochak, graph, dist):
queue = []
# (최소비용, 노드)
heapq.heappush(queue, (0, chulbal))
dist_table[chulbal] = 0
while queue:
i_cost, i = heapq.heappop(queue)
if i_cost > dist_table[i]:
continue
if i == dochak:
return i_cost
for j, j_cost in graph[i]:
new_cost = i_cost + j_cost
if new_cost < dist_table[j]:
dist_table[j] = new_cost
heapq.heappush(queue, (new_cost, j))
print(djikstra(chulbal, dochak, graph, dist_table))
graph[a].append((b, dist)) 한 쪽만 저장하면 됨i_cost를 반환해도 됨import sys
input = sys.stdin.readline
N = int(input())
M = int(input())
INF = float('inf')
graph = [[INF] * (N + 1) for _ in range(N + 1)]
for _ in range(M):
a, b, c = map(int, input().split())
graph[a][b] = min(graph[a][b], c)
for i in range(1, N + 1):
graph[i][i] = 0
for k in range(1, N + 1):
for i in range(1, N + 1):
for j in range(1, N + 1):
graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j])
for i in range(1, N + 1):
for j in range(1, N + 1):
if graph[i][j] >= INF:
print(0, end=" ")
else:
print(graph[i][j], end = " ")
print()