[백준] 1753번: 최단 경로
[백준] 1753번: 최단 경로
📌 문제
https://www.acmicpc.net/problem/1753
📌 설명
가장 대표적인 다익스트라 문제이다. 우선순위 큐를 통해 구현하였다.
📌 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <queue>
#include <vector>
#define INF 300001
using namespace std;
int main() {
int v, e, k;
cin >> v >> e >> k;
vector<pair<int, int>> nodes[20001]; // {도착 노드, 가중치}
for (int i = 0;i < e;i++) {
int x, y, w;
cin >> x >> y >> w;
nodes[x].push_back({ y,w });
}
vector<int> cost(v + 1);
for (int i = 1;i <= v;i++) {
if (i == k)
cost[i] = 0;
else
cost[i] = INF;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push({ 0, k });
while (!pq.empty()) {
int weight = pq.top().first;
int cur = pq.top().second;
pq.pop();
// 이미 최단거리가 존재하는 경우
if (cost[cur] < weight)
continue;
for (int i = 0;i < nodes[cur].size();i++) {
if (weight + nodes[cur][i].second < cost[nodes[cur][i].first]) {
cost[nodes[cur][i].first] = weight + nodes[cur][i].second;
pq.push({ weight + nodes[cur][i].second ,nodes[cur][i].first });
}
}
}
for (int i = 1;i <= v;i++) {
if (cost[i] == INF)
cout << "INF\n";
else
cout << cost[i] << "\n";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import sys
import heapq
input=sys.stdin.readline
n,m=map(int,input().split())
start=int(input())
graph=[[] for _ in range(n+1)]
inf=300001
dist=[inf]*(n+1)
dist[start]=0
for _ in range(m):
u,v,w=map(int,input().split())
graph[u].append((v,w))
q=[]
heapq.heappush(q,(0,start))
while(q):
w,cur=heapq.heappop(q)
if dist[cur]<w:
continue
for nxt,nw in graph[cur]:
if w+nw<dist[nxt]:
dist[nxt]=w+nw
heapq.heappush(q,(dist[nxt],nxt))
for d in dist[1:]:
if d==inf:
print("INF")
else:
print(d)
1
#define INF 300001
적당히 큰 수로 INF를 정의한다.
1
2
3
4
5
6
vector<pair<int, int>> nodes[20001]; // {도착 노드, 가중치}
for (int i = 0;i < e;i++) {
int x, y, w;
cin >> x >> y >> w;
nodes[x].push_back({ y,w });
}
인접 리스트로 노드들의 정보를 관리한다.
1
2
3
4
5
6
7
vector<int> cost(v + 1);
for (int i = 1;i <= v;i++) {
if (i == k)
cost[i] = 0;
else
cost[i] = INF;
}
cost는 시작 노드에서 특정 노드 간 최단 거리를 저장한다. 시작 노드는 0으로 설정하고 나머지 노드는 INF로 초기화한다.
1
2
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push({ 0, k });
우선순위 큐를 선언하고 시작 노드와 가중치를 넣는다. 우선순위 큐 요소의 첫 번째는 가중치가 위치해야 한다. 가중치를 기준으로 정렬되어야 하기 때문이다.
1
2
3
// 이미 최단거리가 존재하는 경우
if (cost[cur] < weight)
continue;
cur은 현재 노드, weight는 현재 노드까지 최소 거리이다. cost[cur] < weight는 이미 cur에 대한 최단 거리가 정의되었다는 것이다. 우선순위 큐 특성 상 최소 가중치를 가진 노드부터 먼저 처리한다. 따라서 이후 과정을 진행하지 않는다.
1
2
3
4
5
6
for (int i = 0;i < nodes[cur].size();i++) {
if (weight + nodes[cur][i].second < cost[nodes[cur][i].first]) {
cost[nodes[cur][i].first] = weight + nodes[cur][i].second;
pq.push({ weight + nodes[cur][i].second ,nodes[cur][i].first });
}
}
nodes[cur][i].first는 다음 노드(cur과 인접한 노드), nodes[cur][i].second는 cur에서 다음 노드까지의 가중치이다. if문의 조건은 시작 노드에서 nodes[cur][i].first로 갈 때 cur을 경유하는 것이 그렇지 않은 경우보다 최단 거리인지 확인한다. 만약 그렇다면 nodes[cur][i].first의 cost 배열을 최단 거리로 초기화하고 pq에 삽입한다.
This post is licensed under CC BY 4.0 by the author.