N

(백준 c++)특정한 최단 경로 본문

백준 알고리즘

(백준 c++)특정한 최단 경로

naeunchan 2021. 5. 28. 17:06
728x90
반응형

문제

방향성이 없는 그래프가 주어진다. 세준이는 1번 정점에서 N번 정점으로 최단 거리로 이동하려고 한다. 또한 세준이는 두 가지 조건을 만족하면서 이동하는 특정한 최단 경로를 구하고 싶은데, 그것은 바로 임의로 주어진 두 정점은 반드시 통과해야 한다는 것이다.

세준이는 한번 이동했던 정점은 물론, 한번 이동했던 간선도 다시 이동할 수 있다. 하지만 반드시 최단 경로로 이동해야 한다는 사실에 주의하라. 1번 정점에서 N번 정점으로 이동할 때, 주어진 두 정점을 반드시 거치면서 최단 경로로 이동하는 프로그램을 작성하시오.

입력

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

출력

첫째 줄에 두 개의 정점을 지나는 최단 경로의 길이를 출력한다. 그러한 경로가 없을 때에는 -1을 출력한다.

 

 

 

특정한 경로 v1, v2를 무조건 지나야 한다.

1 -> v1 -> v2 -> N 의 경우와

1 -> v2 -> v1 -> N 의 경우를 구해 답을 찾아내자.

 

다익스트라 알고리즘을 함수 형태로 빼내서 start와 end를 구할 수 있도록 한다.

dist[end]를 리턴하는데, 이는 start -> end 까지의 최단 경로 값을 나타낸다.

 

long long ans1과 ans2를 선언해 0으로 초기화.

long long인 경우 경로가 없으면 INF인데, 이 값이 int형을 벗어나면 오버플로우가 나기 때문에 틀린 답이 리턴 될 것이다.

 

ans1은 1 -> v1 -> v2 -> N으로 갈 때 최단 경로,

ans2은 1 -> v2 -> v1 -> N으로 갈 때 최단 경로를 나타낸다.

 

두 가지 경우의 최단 경로를 모두 구한 후,

두 값이 INF를 넘지 않으면 둘 중 작은 값을 출력하면 된다.

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#define INF 1000000000

using namespace std;

vector<pair<int, int>> graph[200001];

int dijkstra(int start, int end){
	priority_queue<pair<int, int>> pq;
	vector<int> dist(200001, INF);
	
	pq.push(make_pair(0, start));
	dist[start] = 0;

	while(!pq.empty()){
		int cost = -pq.top().first;
		int current = pq.top().second;

		pq.pop();

		if(dist[current] < cost){
			continue;
		}

		for(int i = 0; i < graph[current].size(); i++){
			int next = graph[current][i].first;
			int nextCost = graph[current][i].second + cost;

			if(dist[next] > nextCost){
				dist[next] = nextCost;
				pq.push(make_pair(-nextCost, next));
			}
		}
	}
	return dist[end];
}

int main(void){
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int N, E, v1, v2;
    long long ans1 = 0, ans2 = 0;
	priority_queue<pair<int, int>> pq;

	cin >> N >> E;

	for(int i = 0; i < E; i++){
		int a, b, c;

		cin >> a >> b >> c;

		graph[a].push_back(make_pair(b, c));
		graph[b].push_back(make_pair(a, c));
	}

	cin >> v1 >> v2;
	
	ans1 += dijkstra(1, v1);
	ans1 += dijkstra(v1, v2);
	ans1 += dijkstra(v2, N);

	ans2 += dijkstra(1, v2);
	ans2 += dijkstra(v2, v1);
	ans2 += dijkstra(v1, N);

	if(ans1 >= INF && ans2 >= INF){
		cout << -1;
	}
	else{
		cout << min(ans1, ans2);
	}

	return 0;
}
728x90
반응형

'백준 알고리즘' 카테고리의 다른 글

(백준 c++)2630 색종이 만들기  (0) 2021.06.02
(백준 c++)9370 미확인 도착지  (0) 2021.05.31
(백준 c++)최단 경로  (0) 2021.05.21
(백준 c++)2805 나무 자르기  (0) 2021.05.04
(백준 c++)1654 랜선 자르기  (0) 2021.05.04