본문 바로가기

코딩/알고리즘

백준 1504 특정한 최단 경로


꼭 거쳐야 하는 노드가 각각


mustVertex1, mustVertex2


라고 하자.



그렇다면


노드1 -> mustVertex1 -> mustVertex2 -> 노드N

노드1 -> mustVertex2 -> mustVertex1 -> 노드N


의 경로 중 짧은 것이 정답이 된다.


각 경로는 다음과 같이 다익스트라 알고리즘을 세번 수행하면 결과를 얻을 수 있다.



1. 노드1에서 시작하는 다익스트라


이것으로 1 ->mustVertex1, 1 -> mustVertex2을 얻을 수 있다.


2. 노드N에서 시작하는 다익스트라


N -> mustVertex1, N -> mustVertex2 를 얻을 수 있다.


3. mustVertex1에서 시작하는 다익스트라


mustVertex1 -> mustVertex2를 얻을 수 있다.



한편, 그래프는 양방향이기 때문에 A->B의 거리가 B->A 거리와 같다.



그리고 각 경로중 하나라도 INT_MAX_에 해당하는 값이 있다면 경로가 없는것이므로 그 경로는 INT_MAX가 되고

두 경로 모두 INT_MAX일 경우 경로가 없으므로 -1을 출력하면 된다.



백준 1753 최단경로 http://deque.tistory.com/67 에서 쓰인 다익스트라 알고리즘을 쓰니 참고.


//deque.tistory.com

#define _CRT_SECURE_NO_WARNINGS
#define INT_MAX_ 2000000000
#define MIN_NUM(a, b) ((a)>(b) ? (b) : (a))

#include <iostream> 
#include <vector> 
#include <queue> 
#include <map>
#include <fstream> 
#include <string> 
#include <algorithm>
#include <functional>

using namespace std;
int N, E;
int mustVertex_1, mustVertex_2;
int OneToV1, OneToV2, V1ToN, V2ToN, V1ToV2;
vector<pair<int, int>> adj[20002];
int dist[20002];
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

void dijkstra(int startNode) {

	for (int i = 1; i <= N; i++) {
		dist[i] = INT_MAX_;
	}
	dist[startNode] = 0;

	pq.push(make_pair(0, startNode));
	while (!pq.empty()) {
		int cost = pq.top().first;
		int now = pq.top().second;
		pq.pop();
		if (dist[now] < cost) continue;
		for (pair<int, int> next : adj[now]) {
			if (dist[next.second] > next.first + cost) {
				pq.push(make_pair(next.first + cost, next.second));
				dist[next.second] = next.first + cost;
			}
		}
	}

	return;
}

int main() {
	scanf("%d %d", &N, &E);

	int from, to, weight;
	for (int i = 0; i < E; i++) {
		scanf("%d %d %d", &from, &to, &weight);
		adj[from].push_back(pair<int, int>(weight, to));
		adj[to].push_back(pair<int, int>(weight, from));
	}
	scanf("%d %d", &mustVertex_1, &mustVertex_2);

	dijkstra(1);

	OneToV1 = dist[mustVertex_1];
	OneToV2 = dist[mustVertex_2];
	if (OneToV1 >= INT_MAX_ && OneToV2 >= INT_MAX_) {
		cout << -1 << endl;
		return 0;
	}

	dijkstra(N);

	V1ToN = dist[mustVertex_1];
	V2ToN = dist[mustVertex_2];

	if (V1ToN >= INT_MAX_ && V2ToN >= INT_MAX_) {
		cout << -1 << endl;
		return 0;
	}

	dijkstra(mustVertex_1);

	V1ToV2 = dist[mustVertex_2];

	if (V1ToV2 >= INT_MAX_) {
		cout << -1 << endl;
		return 0;
	}
	
	int root1 = -1;
	int root2 = -1;
	if (!(OneToV1 >= INT_MAX_ || V1ToV2 >= INT_MAX_ || V2ToN >= INT_MAX_)) {
		root1 = OneToV1 + V1ToV2 + V2ToN;
	}
	if (!(OneToV2 >= INT_MAX_ || V1ToV2 >= INT_MAX_ || V1ToN >= INT_MAX_)) {
		root2 = OneToV2 + V1ToV2 + V1ToN;
	}

	if (root1 == -1 && root2 == -1) {
		cout << -1 << endl;
	}
	else {
		cout << MIN_NUM(root1, root2) << endl;
	}


	return 0;
}




'코딩 > 알고리즘' 카테고리의 다른 글

백준 11657 타임머신  (0) 2018.01.08
백준 1865 웜홀  (0) 2018.01.08
백준 1753 최단경로  (1) 2018.01.06
백준 1766 문제집  (0) 2018.01.05
백준 1516 게임 개발  (0) 2018.01.04