
무언가 넣었는데 100%로 남아있지 않다...ㅠ
한 정점에서 다른 정점까지 최단 경로를 구하는 알고리즘(one to ALL)
최단 거리 테이블초기화음수가 있으면 안되는 이유?
다익스트라는 어떤 정점으로의 최단거리를 계산하면 그것이 확정된 값이라고 믿는다.
이때 음수 간선이 있다면 추후 그 음수 간선을 거쳐서 더 짧은 거리가 나올 수 있기 때문에 음수 가중치가 있으면 안된다.
파이썬 구현
구현 방식은 두가지로 방문하지 않은 노드를 다루는 방식에서 순차탐색과 우선순위 큐로 나뉘는데 시간 복잡도가 더 빠른 우선순위 큐로 구현해보았다.
import heapq
def dijikstra_prorityQ(start):
queue = []
heapq.heappush(queue, (0, start))
distance[start] = 0
while queue:
dist, node = heapq.heappop(queue)
# 큐에서 뽑아낸 거리가 이미 갱신 된 거리보다 클 경우 무시
if distance[node] < dist:
continue
# 큐에서 뽑아낸 노드와 연결된 인접 노드 탐색
for next in graph[node]:
cost = distance[node] + next[1] # start ~ node + node ~ next
if cost < distance[next[0]]:
distance[next[0]] = cost
heapq.heappush(queue, (cost, next[0]))
모든 정점에서 모든 정점까지의 최단 거리를 구하는 알고리즘(all - to - all)
INF = 1e9
# 노드의 개수 및 간선의 개수 입력
V = int(input())
E = int(input())
# 2차원 그래프 만들고 무한으로 초기화
graph = [[INF] * (V + 1) for _ in range(V + 1)]
# 자기 자신에서 자기 자신으로 가는 비용 0으로 초기화
for start in range(1, V + 1):
for end in range(1, V + 1):
if start == end:
graph[start][end] = 0
# 각 간선에 대한 정보를 입력받고, 그 값으로 초기화
for _ in range(E):
# A에서 B로 가는 비용
start, end, price = map(int, input().split())
graph[start][end] = price
# 점화식에 따라 Floyd-Warshall 수행
for k in range(1, V+ 1):
for a in range(1, V + 1):
for b in range(1, V + 1):
graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b])
# 수행된 결과를 출력
for start in range(1, V + 1):
for end in range(1, V + 1):
# 도달 불가일 경우 INF 출력
if graph[start][end] == 1e9:
print('INF')
# 도달 가능하면 거리 출력
else:
print(graph[start][end], end=' ')
음수 가중치를 가진 간선이 있다면 다익스트라 말고 벨만 포드를 사용해야 한다.
V- 1 번 반복BellmanFord(G,w,s):
//초기화 과정
for each u in G.V: //노드를 초기화 하기
distance[v] = inf //모든 노드의 최단거리를 무한으로 지정
parent[v] = null //모든 노드의 부모 노드를 널값으로 지정
distance[s] = 0 //출발점의 최단거리는 0으로 지정한다
//거리측정 과정
for i from 1 to len(G.V): //노드의 숫자만큼
for each (u,v) in G.E: //모든 변을 체크해 최단 거리를 찾아본다.
if distance[u] + w[(u,v)] < distance[v]:
//만약 u를 경유하여 v로 가는 거리가 현재 v의 최단 거리보다 짧으면
distance[v] = distance[u] + w[(u,v)] //그 거리를 v의 최단거리로 지정
parent[v] = u //u를 v의 부모 노드로 지정
//음수 사이클 체크 과정
for each (u,v) in G.E:
if distance[u] + w[(u,v)] < distance[v]:
return false //음수 사이클을 확인하고 알고리즘을 정지
return distance[], parent[]
코딩테스트 문제를 풀면서 좌표가 주어지고, 이를 기준으로 인접한 노드를 탐색할 경우 유용하게 쓸 수 있는 테크닉.
x,y 좌표의 변화를 리스트에 담아서 상,하,좌,우 이동을 편리하게 할 수 있다.
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
def bfs(x, y):
queue = deque()
queue.append((x,y))
while queue:
x, y = queue.popleft()
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < n and 0 <= ny < m and graph[nx][ny] == 1:
queue.append((nx, ny))
graph[nx][ny] = graph[x][y] + 1
return graph[n-1][m-1]
월요병인가 집중도가 제일 낮았던 날.
화요일은 심기일전해서 다시 집중해보자