📌 문제 출처: BOJ 1504 - 특정한 최단 경로
제목
( 7/28 - class4 : 백준1504 )
문제 유형
- 최단 경로
- Dijkstra (다익스트라)
풀이 방법 도출
- 다익스트라 3회 실행: 시작점(1), 경유지(v1), 경유지(v2)에서
- 두 가지 경로 고려:
- 1 → v1 → v2 → N
- 1 → v2 → v1 → N
- 두 경로 중 가능한 최소값을 선택
시간 복잡도
- 다익스트라 3회: O((E + V) log V)
- V ≤ 800, E ≤ 200,000이므로 충분히 통과 가능
코드
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
using ll = long long;
int n, e;
vector<pair<int,int>> adj[805];
const int INF = 1e9+10;
int v1, v2;
vector<int> dijkstra(int start) {
priority_queue<pair<int,int>,
vector<pair<int,int>>,
greater<pair<int,int>> > pq;
vector<int> dist(n+1, INF);
dist[start] = 0;
pq.push({dist[start], start});
while(!pq.empty()) {
auto cur = pq.top(); pq.pop();
if(dist[cur.Y] != cur.X) continue;
for(auto nxt : adj[cur.Y]) {
if(dist[nxt.Y] <= dist[cur.Y] + nxt.X) continue;
dist[nxt.Y] = dist[cur.Y] + nxt.X;
pq.push({dist[nxt.Y], nxt.Y});
}
}
return dist;
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> e;
while(e--) {
int a, b, c;
cin >> a >> b >> c;
adj[a].push_back({c, b});
adj[b].push_back({c, a});
}
cin >> v1 >> v2;
auto d_from_1 = dijkstra(1);
auto d_from_v1 = dijkstra(v1);
auto d_from_v2 = dijkstra(v2);
ll path1 = 1LL*d_from_1[v1] + d_from_v1[v2] + d_from_v2[n];
ll path2 = 1LL*d_from_1[v2] + d_from_v2[v1] + d_from_v1[n];
ll ans = min(path1, path2);
if(ans >= INF) cout << -1;
else cout << ans;
}
댓글남기기