문제풀이/백준

[C++] 백준 1504 - 특정한 최단 경로

레옹 2023. 10. 9. 00:05
 

1504번: 특정한 최단 경로

첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 ≤ N ≤ 800, 0 ≤ E ≤ 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존

www.acmicpc.net

풀이

1. 첫노드→N1 로가는 짧은경로 + N1 → N2로가는 경로 + N2에서 n번째노드로 가는 경로

2. 첫노드→N2 로가는 짧은경로 + N2 → N1로가는 경로 + N1에서 n번째노드로 가는 경로

둘중 짧은 것이 답이다.

 

 

코드

#include <bits/stdc++.h>

using namespace std;

vector<pair<int,int>> adj[801];

int n,e;
int v1,v2;

int Dijkstra(int src, int nend){
   vector<int> dist(801, 100000000);
   dist[src] = 0;
   priority_queue<pair<int,int>> q;
   q.push(make_pair(0,src));
   
   while(!q.empty()){
       int cost = -q.top().first;
       int node = q.top().second;
       q.pop();
       
       if(dist[node] < cost) continue;
       
       for(int i = 0; i < adj[node].size(); i++){
           int nextNode = adj[node][i].first;
           int nextCost = adj[node][i].second + cost;
           
           if(dist[nextNode] > nextCost){
               dist[nextNode] = nextCost;
               q.push(make_pair(-nextCost, nextNode));
           }
       }
   }
   return dist[nend];
}

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> n >> e;
    int b,nb,c;
    for(int i =0 ; i < e; i++){
        cin >> b >> nb >> c;
        adj[b].push_back(make_pair(nb,c));
        adj[nb].push_back(make_pair(b,c));
    }
    cin >> v1 >> v2;
    int answer = 100000000;
    answer = min(answer, Dijkstra(1,v1) + Dijkstra(v1,v2) + Dijkstra(v2,n));
    answer = min(answer, Dijkstra(1,v2) + Dijkstra(v2,v1) + Dijkstra(v1,n));
   if(answer != 100000000)
   cout << answer;
   else
   cout << -1;
    return 0;
}