(0, 시작점)을 추가v라고 할 때, v와 이웃한 정점들에 대해 최단 거리 테이블 값보다 v를 거쳐가는 것이 더 작은 값을 가질 경우 최단 거리 테이블의 값을 갱신하고 우선순위 큐에 (거리, 이웃한 정점의 번호)를 추가#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
int v, e, st;
// {비용, 정점 번호}
vector<pair<int, int>> adj[20005];
const int INF = 1e9+10;
int d[20005];
int main(void) {
sync_with_stdio(0);
cin.tie(0);
cin >> v >> e >> st;
fill(d, d + v + 1, INF);
while(e--) {
int u, v, w;
cin >> u >> v >> w;
adj[u].push_back({w, v});
}
priority_queue<pair<int, int>,
vector<pair<int, int>>,
greater<pair<int, int>>> pq;
d[st] = 0; // 시작점
pq.push({d[st], st}); // 우선순위 큐에 (0, 시작점) 추가
while(!pq.empty()) {
auto cur = pq.top(); pq.pop();
if(d[cur.Y] != cur.X) continue; // 거리가 d에 있는 값과 다를 경우 넘어감
for(auto nxt : adj[cur.Y]) {
if(d[nxt.Y] <= d[cur.Y] + nxt.X) continue; // cur를 거쳐가는 것이 더 작은 값을 가질 경우 d[nxt.Y]를 갱신하고 우선순위 큐에 {거리, nxt.Y}를 추가
d[nxt.Y] = d[cur.Y] + nxt.X;
pq.push({d[nxt.Y], nxt.Y});
}
}
for (int i = 1; i <= v; i++) {
if (d[i] == INF) cout << "INF\n";
else cout << d[i] << '\n';
}
}
최단 거리 테이블과 더불어 시작점에서 나에게 올 때 직전에 어디를 방문했는지 기록하는 테이블인 pre 테이블을 둔다.
// for문 내부
if(d[nxt.Y] <= d[cur.Y] + nxt.X) continue;
d[nxt.Y] = d[cur.Y] + nxt.X;
pq.push({d[nxt.Y], nxt.Y});
pre[nxt.Y] = cur.Y; // 최단 거리의 갱신이 일어날 때 pre 값을 갱신한다.
{
// 생략
cout << d[en] << '\n';
vector<int> path;
int cur = en;
while(cur != st) {
path.push_back(cur);
cur = pre[cur];
}
path.push_back(cur);
reverse(path.begin(), path.end());
cout << path.size() << '\n';
for(auto x : path) cout << x << ' ';
}