백준 #1504 특정한 최단 경로

1 minute read

백준 #1504 특정한 최단 경로

그래프와 그래프 내의 두 정점이 주어졌을 때 두 정점을 무조건 지나가면서 정점 1부터 N(마지막 정점)까지의 최단 경로를 구하는 문제. 두 정점을 방문하는 순서대로 다익스트라 알고리즘을 통해 최단경로를 계산한 후 더 짧은 경로를 출력한다.

정점 v1, v2가 주어졌을 때

  • 1경로: 1 → v1 → v2 → N
  • 2경로: 1 → v2 → v1 → N

1 → v1, v1 → v2(양방향이기 때문에 v2 → v1과 같음), v2 → N, 1 → v2, v1 → N을 각각 계산한다.

#include <iostream>
#include <memory.h>
#include <bits/stdc++.h>
#include <queue>
#include <vector>
#include <algorithm>

#define INF 1e8

using namespace std;

int N, E;
vector<pair<int, int>> graph[801];
int dist[801];


int dijkstra(int start, int dest) {
    fill(dist, dist + N + 1, INF);
    priority_queue<pair<int, int>> q;
    dist[start] = 0;
    q.push({-dist[start], start});
    while(!q.empty()) {
        int here = q.top().second;
        q.pop();
        for(auto it = graph[here].begin(); it != graph[here].end(); it++) {
            int next = it->first;
            int nextCost = it->second;
            if(dist[next] > dist[here] + nextCost) {
                dist[next] = dist[here] + nextCost;
                q.push({-dist[next], next});
            }
        }
    }
    return dist[dest];
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> N >> E;
    int v1, v2;
    for(int i = 0; i < E; i++) {
        int from, to, val;
        cin >> from >> to >> val;
        graph[from].push_back({to, val});
        graph[to].push_back({from, val});
    }
    cin >> v1 >> v2;
    int first_1, first_2, second_1, second_2, middle, firstTotal, secondTotal, realTotal;
    first_1 = dijkstra(1, v1);
    middle = dijkstra(v1, v2);
    first_2 = dijkstra(v2, N);
    second_1 = dijkstra(1, v2);
    second_2 = dijkstra(v1, N);
    firstTotal = first_1 + middle + first_2;
    secondTotal = second_1 + middle + second_2;
    realTotal = min(firstTotal, secondTotal);
    if(realTotal >= INF) {
        realTotal = -1;
    }
    cout << realTotal;

    return 0;
}

Comments