📌 문제 출처: 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;
}
 
      
댓글남기기