Dijkstra Algorithm
그래프에서 최단 거리를 구하는 알고리즘
특정 노드에서 다른 노드들의 최단 거리 구하기
기능
- 출발 노드와 모든 노드 간의 최단 거리 탐색
특징
- 에지가 모두 양수
시간 복잡도
- O(에지 수*log(노드수))
최단거리 구하기이기 때문에
BFS와 상당히 유사 (큐 이용/방문리스트활용)
그 세부 버전 같기도(최단거리 계산 추가된)
🥇골드5
1753번: 최단경로
첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 ≤ V ≤ 20,000, 1 ≤ E ≤ 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 ≤ K ≤ V)가
www.acmicpc.net
1) 거리 리스트에서 방문하지 않은, 현재 값이 가장 작은 노드 선택
2) 해당 노드와 연결된 노드들의 최단 거리 값을 업데이트 ( 선택 노드의 리스트값+에지 가중치, 현재 값 중에서 작은 것)
큐가 빌 때까지 반복하기
3) 큐가 빌 때까지 1-2 반복
+최대값!
sys.maxsize
from queue import PriorityQueue #우선순위 큐
import sys
V,E = map(int,sys.stdin.readline().split()) #정점의 개수 V와 간선의 개수 E
K = int(sys.stdin.readline()) #시작 정점의 번호 K
result = [sys.maxsize] * (V+1) #최단거리결과리스트
visited = [False]* (V+1) #방문리스트
nearList = [[] for _ in range(V+1)] #인접리스트 + 가중치
Myqueue = PriorityQueue() # 왜냐면,,,,왜?
#인접리스트+가중치 저장
for _ in range(E):
u,v,w = map(int,sys.stdin.readline().split()) # u에서 v로 가는 가중치 w인 간선
nearList[u].append((v,w))
#시작점 설정하기
Myqueue.put((0,K)) #put/get
result[K] = 0
#탐색시작
while Myqueue.qsize() > 0:
Now = Myqueue.get() #첫번째 요소(거리)의 크기대로 항상 정렬
nowNode = Now[1]
#방문확인(처음도착 다음의 도착은 무조건 더 길으므로)
if visited[nowNode]:
continue
visited[nowNode] = True
#인접노드 확인
for cha in nearList[nowNode]:
nextNode = cha[0]
plusdis = cha[1]
if result[nextNode] > result[nowNode] + plusdis:#최소거리업데이트
result[nextNode] =result[nowNode] + plusdis
Myqueue.put((result[nextNode],nextNode)) #변경 전이 더 컸으면 다시 확인해볼 필요 없음
#결과
for i in range(1,V+1):
if visited[i]:
print(result[i])
else:
print("INF")#도달할 수 없는 노드
왜 우선순위 큐를 사용해야 하는지 잘 이해를 못하겠다.
여러 경로가 있을 수 있는데 노드를 다시 방문할 수 없으므로 개중 가장 짧은 것을 알기 위해..? 하는 건가..?
글 읽기 - 왜 우선순위 큐를 사용해야 하는지..??????ㅜㅜ
댓글을 작성하려면 로그인해야 합니다.
www.acmicpc.net
차례대로 하나씩 최소 거리를 확정하는 것이기 때문(노드 get 시 확정!)
get한 노드 중심으로 연결 노드들의 값을 갱신(더 최소일 시)하여 더 최소로 만드려고 하므로
우선순위 큐를 이용하여 제일 최소 값을 확정시키고 나머지도 더 적어질 여지가 있는지 확인하는 것!
🥇골드5
1916번: 최소비용 구하기
첫째 줄에 도시의 개수 N(1 ≤ N ≤ 1,000)이 주어지고 둘째 줄에는 버스의 개수 M(1 ≤ M ≤ 100,000)이 주어진다. 그리고 셋째 줄부터 M+2줄까지 다음과 같은 버스의 정보가 주어진다. 먼저 처음에는 그
www.acmicpc.net
위 문제와 거의 일치한다.
그냥 모든 최단거리가 아니라 하나의 최단거리만 출력하면 됨
from queue import PriorityQueue #우선순위 큐
import sys
V = int(sys.stdin.readline()) #도시
E = int(sys.stdin.readline()) #버스
result = [sys.maxsize] * (V+1) #최단거리결과리스트
visited = [False]* (V+1) #방문리스트
nearList = [[] for _ in range(V+1)] #인접리스트 + 가중치
Myqueue = PriorityQueue() # 왜냐면,,,,왜?
#인접리스트+가중치 저장
for _ in range(E):
u,v,w = map(int,sys.stdin.readline().split()) # u에서 v로 가는 가중치 w인 간선
nearList[u].append((v,w))
K,F = map(int,sys.stdin.readline().split()) #시작 / 끝
#시작점 설정하기
Myqueue.put((0,K)) #put/get
result[K] = 0
#탐색시작
while Myqueue.qsize() > 0:
Now = Myqueue.get() #첫번째 요소(거리)의 크기대로 항상 정렬
nowNode = Now[1]
#방문확인(처음도착 다음의 도착은 무조건 더 길으므로)
if visited[nowNode]:
continue
visited[nowNode] = True
#인접노드 확인
for cha in nearList[nowNode]:
nextNode = cha[0]
plusdis = cha[1]
if result[nextNode] > result[nowNode] + plusdis:#최소거리업데이트
result[nextNode] =result[nowNode] + plusdis
Myqueue.put((result[nextNode],nextNode)) #변경 전이 더 컸으면 다시 확인해볼 필요 없음
#결과
print(result[F])
✳️플래티넘 4
1854번: K번째 최단경로 찾기
첫째 줄에 n, m, k가 주어진다. (1 ≤ n ≤ 1000, 0 ≤ m ≤ 2000000, 1 ≤ k ≤ 100) n과 m은 각각 김 조교가 여행을 고려하고 있는 도시들의 개수와, 도시 간에 존재하는 도로의 수이다. 이어지는 m개의 줄에
www.acmicpc.net
어떻게 최단 경로가 아닌 "K"번째 최단 경로를 찾을 수 있을까??
+ 다익스트라 알고리즘에서해당 노드를 다시 사용하지 않도록 설정하는 부분은 삭제가 필요함.
+ 최단 거리 리스트를 k개의 열을 갖도록 초기화함
- 우선순위 큐에서 연결된 노드와 가중치 데이터를 pop
- 연결 노드의 k번째 경로와 신규 경로를 비교해 신규 경로가 더 작을 때 업데이트 / 이때 거리 배열을 오름차순으로 정렬하고 유선순위 큐에 연결 노드를 추가
- 위 단계를 우선순위 큐가 비워질 때까지 반복
- 결과 리스트를 탐색하며 k번째 경로가 무한대면 -1 출력 / 그 외는 해당 경로값 출력
+heapq / priorityqueue
[Python/파이썬] PriorityQueue & heapq / 우선순위큐와 힙큐
백준에서 문제를 풀다가 Priority Queue 와 Heapq 차이로 문제 시간에 걸릴 수도 안 걸릴 수도 있다는걸 알았다. Priority Queue 와 Heaq의 차이를 알아보기 위해서 라이브러리를 뜯어서 맛보자 1. 라이브러
slowsure.tistory.com
우선순위 큐를 heapq로 구현하는 방법 숙지하기
import heapq #우선순위 큐
import sys
N,M,K = map(int,sys.stdin.readline().split())
nearList= [[] for _ in range(N+1)] #노드정보
distance = [[sys.maxsize]*K for _ in range(N+1)] #거리 리스트를 큰 값으로, K개
#인접리스트+가중치 저장
for _ in range(M):
a,b,c = map(int,sys.stdin.readline().split()) # u에서 v로 가는 가중치 w인 간선
nearList[a].append((b,c))
#시작점 설정하기
pq = [(0,1)] #가중치 우선 우선순위 큐
distance[1][0] = 0 # 출발 노드
#변형 다익스트라 탐색시작
while pq:
c, n = heapq.heappop(pq)
for nN, nC in nearList[n]:
if distance[nN][K-1] > c + nC:
distance[nN][K-1] = c + nC
distance[nN].sort()
heapq.heappush(pq,(c + nC,nN))
#결과
for i in range(1, N+1):
if distance[i][K-1] == sys.maxsize: #도달불가
print(-1)
else:
print(distance[i][K-1])
모오든 경로를 다 탐색하는..
건가??
아악
나중에 한번 더 혼자 풀어야지
'📊 Algorithm > Algorithm 주제별 정리' 카테고리의 다른 글
🧚♂️알고리즘🧚♂️ - 그래프 - 플로이드 워셜 (0) | 2023.07.12 |
---|---|
🧚♂️알고리즘🧚♂️ - 그래프 - 벨만 포드 (0) | 2023.07.08 |
🧚알고리즘🧚-그래프- 위상 정렬 (0) | 2023.07.01 |
🧚알고리즘🧚-그래프- 유니온 파인드 (0) | 2023.06.28 |
🧚♂️알고리즘🧚♂️ - 그래프 - 그래프기초 (0) | 2023.06.24 |