정점과 간선을 이용해 사이클이 이루어지지 않게 구성된 자료 구조
노드의 최대 branch가 2인 트리
현재까지 알고 있던 최단 경로를 계속해서 갱신
그래프는 실제로 컴퓨터 안에서 처리할 때 이차원 배열 형태로 처리해야 한다.
해당 표는 특정 행에서 열로 가는 비용! 을 뜻함
최소 비용을 찾을 때, 탐색은 힙 구조를 활용해야 선형 탐색(O(n^2))보다 빠른 O(N*logN)으로 진행할 수 있다.
import sys
input = sys.stdin.readline
INF = int(1e9)
n, m = map(int, input().split())
start = int(input())
# 주어지는 그래프 정보 담는 N개 길이의 리스트
graph = [[] for _ in range(n+1)]
visited = [False] * (n+1) # 방문처리 기록용
distance = [INF] * (n+1) # 거리 테이블용
for _ in range(m):
a, b, c = map(int, input().split())
graph[a].append((b, c))
# 방문하지 않은 노드이면서 시작노드와 최단거리인 노드 반환
def get_smallest_node():
min_value = INF
index = 0
for i in range(1, n+1):
if not visited[i] and distance[i] < min_value:
min_value = distance[i]
index = i
return index
# 다익스트라 알고리즘
def dijkstra(start):
# 시작노드 -> 시작노드 거리 계산 및 방문처리
distance[start] = 0
visited[start] = True
# 시작노드의 인접한 노드들에 대해 최단거리 계산
for i in graph[start]:
distance[i[0]] = i[1]
# 시작노드 제외한 n-1개의 다른 노드들 처리
for _ in range(n-1):
now = get_smallest_node() # 방문X 면서 시작노드와 최단거리인 노드 반환
visited[now] = True # 해당 노드 방문처리
# 해당 노드의 인접한 노드들 간의 거리 계산
for next in graph[now]:
cost = distance[now] + next[1] # 시작->now 거리 + now->now의 인접노드 거리
if cost < distance[next[0]]: # cost < 시작->now의 인접노드 다이렉트 거리
distance[next[0]] = cost
dijkstra(start)
for i in range(1, n+1):
if distance[i] == INF:
print('도달 할 수 없음')
else:
print(distance[i])
좋아요공감
공유하기글 요소
import heapq
import sys
input = sys.stdin.readline # 빠른 입력
INF = int(1e9) # 무한을 의미하는 값으로 10억 설정
# 노드의 개수, 간선의 개수를 입력받기
n, m = map(int, input().split())
# 시작 노드 번호를 입력받기
start = int(input())
# 최단거리 테이블
distance = [INF]*(n+1)
# 노드 연결정보
graph = [[] for i in range(n+1)]
for _ in range(m):
# a번노드에서 b번 노드로 가는 비용c
a,b,c = map(int, input().split())
graph[a].append((b,c))
# 다익스트라 알고리즘(최소힙 이용))
def dijkstra(start):
q=[]
# 시작 노드
heapq.heappush(q, (0,start))
distance[start] = 0
while q:
# 가장 최단거리가 짧은 노드에 대한 정보 꺼내기
dist, now = heapq.heappop(q)
# 이미 처리된 노드였다면 무시
# 별도의 visited 테이블이 필요없이, 최단거리테이블을 이용해 방문여부 확인
if distance[now] < dist:
continue
# 선택된 노드와 인접한 노드를 확인
for i in graph[now]:
cost = dist + i[1]
# 선택된 노드를 거쳐서 이동하는 것이 더 빠른 경우
if cost < distance[i[0]]:
distance[i[0]] = cost
heapq.heappush(q, (cost,i[0]))
# 다익스트라 알고리즘수행
dijkstra(start)
# 모든 노드로 가기 위한 최단 거리를 출력
for i in range(1, n+1):
# 도달할 수 없는 경우
if distance[i] == INF:
print("infinity")
else:
print(distance[i])
시작노드를 1개만 설정하는 것이 아닌 다수 즉, 모든 노드에서 모든 노드까지의 최단 거리를 구하는 방법
점화식 :
D[a][b] = min(D[a][b],D[a][k]+D[k][b])
시간 복잡도 : 매 단계마다 O(n^2) 연산 수행 ➡️ 총 시간 복잡도 O(n^3)
노드와 간선 사이 정보를 2차원 리스트 형태의 거리 테이블에 갱신
0번부터 n-1번까지 확인하면서 거리 테이블 갱신한다.
for k in range(n):
for i in range(n):
for j in range(n):
graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j])
자료구조 생성, 초기화
INF = 노드개수 * 최대가중치 +1
INF 값은?
INF = 노드개수 * 최대가중치 +1
⬇️
1~N모드에서 모든 노드로 최대가중치로 이동하는 경우 - 자기자신으로 이동하는 경우 보다 큰 값으로 잡아야 버틸 수 있음. 위의 식은 안전한 값을 공식화 한 것
DONT DO THIS
1.INF = sys.maxsize : 연산에 시간이 오래걸려서 시간초과 발생 가능
2. int(1e9) : 극단적인 케이스에서 버틸 수 없음
arr = [[INF j in range(n)] for i in range(n)]
메인 로직
for k in range(n):
for i in range(n):
for j in range(n):
arr[i][j] = min(arr[i][j], arr[i][k] + arr[k][j])
```
import sys
INF = int(1e9)
n = int(input())
m = int(input())
# 2차원 거리테이블 리스트 초기화
graph = [[INF] * (n+1) for _ in range(n+1)]
# 자신의 노드간의 거리는 0으로 변경
for i in range(1, n+1):
for j in range(1, n+1):
if i == j:
graph[i][j] = 0
# 주어지는 그래프 정보 입력
for _ in range(m):
# a -> b로 가는 비용은 c
a, b, c = map(int, input().split())
graph[a][b] = c
# k=거쳐가는 노드
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('도달할 수 없음', end=' ')
else:
print(graph[i][j], end=' ')
print()
시작 정점으로부터 다른 정점까지의 최단 경로를 찾기 위한 알고리즘
INF = float('inf')
V, E = map(int, input().split())
edges = []
for _ in range(E):
s, d, w = map(int, input().split())
edges.append((s, d, w))
def bellman-ford(start):
dist = [INF] * (V + 1)
dist[start] = 0
for i in range(V):
for s, d, w in edges:
if dist[s] != INF and dist[d] > dist[s] + w:
if i == V - 1: # i가 v-1이면 v번째 간선 추가이므로 음수 사이클
return -1
dist[d] = dist[s] + w
return dist
print(bellman-ford(0))
[참고]