BFS에서 응용하는 가중치 그래프에서의 최단 경로를 구하는 방법에는 3가지가 있다.
- 출발 노드를 설정
- 최단 거리 테이블을 초기화
- 방문하지 않은 노드 중에서 최단 거리가 가장 짧은 노드를 선택
- 해당 노드를 거쳐 다른 노드로 가는 비용을 계산하여 최단 거리 테이블을 갱신
- 위 과정에서 3번과 4번을 반복
이때 최단 거리가 가장 짧은 노드를 매번 선형 탐색해야 하므로 전체 시간 복잡도는 O(V2)이다.
하지만 노드의 개수가 10000개가 넘어가면 시간초과가 발생할 수 있다.
따라서 우선순위 큐(최소 힙)를 이용해서 최단거리를 구한다. 시간 복잡도 : O(ElogV)
#다익스트라 알고리즘(개선 후) - 최소 힙 사용
import heapq
from sys import stdin as s
s=open("input.txt","rt")
INF = int(1e9)
n,m = map(int, s.readline().split())
start= int(s.readline())
graph = [[] for i in range(n+1)]
distance = [INF] *(n-1)
for _ in range(m):
a,b,c = map(int, s.readline().split())
#a번 노드에서 b번 노드로 가는 비용이 c라는 의미
graph[a].append((b,c))
def dijkstra(start):
q=[]
heapq.heappush(q,(0,start))
distance[start]=0
while q:
dist,now = heapq.heappop(q)
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])
import heapq
# 오름차순 힙 정렬(Heap Sort)
def heapsort(iterable):
h = []
result = []
# 모든 원소를 차례대로 힙에 삽입
for value in iterable:
heapq.heappush(h, value)
# 힙에 삽입된 모든 원소를 차례대로 꺼내어 담기
for i in range(len(h)):
result.append(heapq.heappop(h))
return result
result = heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
print(result)
#result : 0,1,2,3,4,5,6,7,8,9
import heapq
# 내림차순 힙 정렬(Heap Sort)
def heapsort(iterable):
h = []
result = []
# 모든 원소를 차례대로 힙에 삽입
for value in iterable:
heapq.heappush(h, -value)
# 힙에 삽입된 모든 원소를 차례대로 꺼내어 담기
for i in range(len(h)):
result.append(-heapq.heappop(h))
return result
result = heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
print(result)
#9,8,7,6,5,4,3,2,1,0
처음에 음수로 정렬한뒤 음수를 뺀 값을 출력해준다.
- 출발 노드를 설정
- 최단 거리 테이블을 초기화
- 다음의 과정을 N-1번 반복
3-1. 전체 간선 E개를 하나씩 확인
3-2. 각 간선을 거쳐 다른 노드로 가는 비용을 계산하여 최단 거리 테이블을 갱신
def bellmanford(V, K, graph, dist):
dist[K] = 0
minusCycle = False
for i in range(V): # 정점 수 만큼 반복
for j in graph[i]: # 모든 간선 확인
cost = j[1]
if dist[j[0]] > dist[i] + cost:
dist[j[0]] = dist[i] + cost
if i == V - 1: # (V-1)번 이후에도 갱신되면 음수 사이클
minusCycle = True
return dist[1:] if minusCycle is False else "음수 사이클"
#n의 갯수가 많을 수록 불리 -> 시간 복잡도 o(n3)
INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정
#노드의 개수 및 간선의 개수를 입력받기
n=int(input())
m=int(input())
graph = [[INF]*(n+1) for _ in range(n+1)]
for a in range(1,n+1):
for b in range(1,n+1):
if a==b:
graph[a][b]=0
# 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화
for _ in range(m):
a,b,c= map(int, input().split())
graph[a][b]=c
for k in range(1,n+1):
for a in range(1,n+1):
for b in range(1,n+1):
graph[a][b] = min(graph[a][b],graph[a][k]+graph[k][b])
for a in range(1,n+1):
for b in range(1,n+1):
if graph[a][b]==INF:
print("INFINTY",end =" ")
else:
print(graph[a][b],end= " ")
print()
Ref)
https://velog.io/@juwon9733/%EC%B5%9C%EB%8B%A8-%EA%B2%BD%EB%A1%9C-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98
https://velog.io/@1998yuki0331/Python-%EA%B0%80%EC%A4%91%EC%B9%98-%EA%B7%B8%EB%9E%98%ED%94%84%EC%97%90%EC%84%9C%EC%9D%98-%EC%B5%9C%EB%8B%A8-%EA%B2%BD%EB%A1%9C
이것이 취업을 위한 코딩 테스트다 WITH 파이썬 편
https://heytech.tistory.com/67