습관처럼

백준 1504 - 특정한 최단 경로 본문

Algorithms/BOJ

백준 1504 - 특정한 최단 경로

dev.wookii 2020. 2. 20. 16:01

https://www.acmicpc.net/problem/1504

 

1504번: 특정한 최단 경로

첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 ≤ N ≤ 800, 0 ≤ E ≤ 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존재하며, 그 거리가 c라는 뜻이다. (1 ≤ c ≤ 1,000) 다음 줄에는 반드시 거쳐야 하는 두 개의 서로 다른 정점 번호가 주어진다.

www.acmicpc.net

문제 설명


방향성이 없는 그래프가 주어질때, 1번 정점에서 N번 정점으로 최단 거리로 이동하려고 한다.

또한, 두 가지 조건을 만족하면서 이동하는 특정한 최단 경로 구한다.

그것은 바로 임의로 주어진 두 정점은 반드시 통과해야 한다는 것.

한번 이동했던 정점은 물론, 한번 이동했던 간선도 다시 이동할 수 있다. 하지만 반드시 최단 경로로 이동해야 한다는 사실에 주의하라.

1번 정점에서 N번 정점으로 이동할 때, 주어진 두 정점을 반드시 거치면서 최단 경로로 이동하는 프로그램을 작성하시오.

 

 

접근 방식


문제 접근 방식은 최단거리를 떠올리게 되고 Dijkstra에서 조건을 추가하는 방식으로 문제를 해결하였다.

 

 

코드


#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <functional>
const int INF =987654321;
using namespace std;
int n,m;    
int sp,ep;
vector<pair<int,int> >v[200001];
vector<int>dijkstra(int start, int num){
    vector<int>weight(num,INF);
    priority_queue<pair<int,int> >pq;
    weight[start]=0;
    pq.push(make_pair(0,start));
    while(!pq.empty()){
        int cost = pq.top().first;
        int vert = pq.top().second;
        pq.pop();
        for(int i=0;i<v[vert].size();i++){
            int neighbor= v[vert][i].first;
            int neighbordistance = v[vert][i].second+cost;
            if(neighbordistance < weight[neighbor]){
                weight[neighbor]=neighbordistance;
                pq.push(make_pair(-neighbordistance,neighbor));
            }
        }
    }
    return weight;
}
int main(){
   cin>>n>>m;    
   n++;
   for(int i=0;i<m;i++){
       int start,end,cost;
       cin>>start>>end>>cost;
       //양방향성
       v[start].push_back(make_pair(end,cost));
       v[end].push_back(make_pair(start,cost));
   }
   cin>>sp>>ep;
   vector<int> result = dijkstra(1, n);
   vector<int> temp1 = dijkstra(sp, n);
   vector<int> temp2 = dijkstra(ep, n);
	//1. 1 -> startpoint -> endpoint -> N
    //2. 1 -> endpoint -> startpoint -> N
   int answer = min((result[sp] + temp1[ep] + temp2[n - 1]), (result[ep] + temp2[sp] + temp1[n - 1]));
   if (answer >= INF || answer < 0) cout << -1 << "\n";
   else cout << answer << "\n";
   return 0;
}

 

 

funny algorithms :0 ~

'Algorithms > BOJ' 카테고리의 다른 글

백준 16236 - 아기상어  (0) 2020.03.04
백준 14500 - 테트로미노  (0) 2020.03.03
백준 1916 - 최소비용 구하기  (0) 2020.02.18
백준 1018 - 체스판 다시 칠하기  (0) 2020.02.10
백준 2309 - 일곱 난쟁이  (0) 2020.02.07