[ ALGORITHM ]/[ 백 준 ]
[BAEKJOON] 1504번 : 특정한 최단 경로
HiStar__
2020. 9. 8. 16:04
문 제
소 스 코 드
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
constexpr int INF{ 0x7fff'0000 };
struct Edge {
int nV;
int mDis;
bool operator <(const Edge& other) const {
return mDis > other.mDis;
}
};
class Graph {
public:
Graph() = delete;
Graph(const int& v) {
mGraph.resize(v + 1);
mDist.resize(v + 1);
}
void AddEdge(const int& a, const int b, const int c) {
mGraph[a].emplace_back(Edge{ b, c });
mGraph[b].emplace_back(Edge{ a, c });
}
void Display() {
for (int i = 1; i < mGraph.size(); ++i) {
std::cout << i << " : ";
for (const auto& a : mGraph[i]) {
std::cout << a.nV << " : " << a.mDis << " ";
}
std::cout << '\n';
}
}
void Dijkstra(const int& start) {
if (start < 1 || start > mGraph.size()) return;
while (!pQue.empty()) pQue.pop();
for (int i = 1; i < mDist.size(); ++i) mDist[i] = INF;
mDist[start] = 0;
for (int i = 1; i < mDist.size(); ++i) pQue.push(Edge{ i, mDist[i] });
while (!pQue.empty()) {
Edge now{ pQue.top() };
pQue.pop();
if (mDist[now.nV] < now.mDis) continue;
for (const auto & a : mGraph[now.nV]) {
int temp{ mDist[now.nV] + a.mDis };
if (mDist[a.nV] > temp) {
mDist[a.nV] = temp;
pQue.push(Edge{ a.nV, mDist[a.nV] });
}
}
}
}
void GoThrough(const int& v1, const int& v2) {
int p1[4]{ 0, };
int p2[4]{ 0, };
Dijkstra(1);
p1[0] = mDist[v1];
p2[0] = mDist[v2];
Dijkstra(v1);
p1[1] = mDist[v2];
p2[1] = mDist[mGraph.size() - 1];
Dijkstra(v2);
p1[2] = mDist[mGraph.size() - 1];
p2[2] = mDist[v1];
for (int i = 0; i < 3; ++i) {
if (p1[i] == INF) {
p1[3] = -1;
break;
}
else p1[3] += p1[i];
}
for (int i = 0; i < 3; ++i) {
if (p2[i] == INF) {
p2[3] = -1;
break;
}
else p2[3] += p2[i];
}
std::cout << std::min(p1[3], p2[3]);
}
private:
std::vector<std::vector<Edge>> mGraph; // weight, pos
std::vector<int> mDist; // now, save;
std::priority_queue<Edge> pQue;
};
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
std::cout.tie(NULL);
int N, E;
std::cin >> N >> E;
Graph graph(N);
int a, b, c;
for (int i = 0; i < E; ++i) {
std::cin >> a >> b >> c;
graph.AddEdge(a, b, c);
}
int v1, v2;
std::cin >> v1 >> v2;
graph.GoThrough(v1, v2);
return 0;
}
풀 이
더보기
[ 백준 ] 1753번 : 최단경로에서 사용한 다익스트라 알고리즘을 통하여 길을 찾는 방법을 3번 사용하여 구현을 하였습니다.
먼저 v1, v2를 거쳐야하기 때문에
( 1 -> v1 ) + ( v1 -> v2 ) + ( v2 -> N )
( 1 -> v2 ) + ( v2 -> v1 ) + ( v1 -> N )
두 가지 경로의 거리를 확인해야 한다.
다익스트라 알고리즘의 경우.
dist배열에 시작지점에서 모든 점까지의 거리를 확인할 수 있기 때문에,
시작 지점이 1일 경우 : ( 1 -> v1 ) , ( 1 -> v2 )
시작 지점이 v1일 경우 : ( v1 -> v2 ) , ( v1 -> N )
시작 지점이 v2일 경우 : ( v2 -> v1 ) , ( v2 -> N )
다익스트라 알고리즘을 3번 1, v1, v2 를 확인하면 값을 구할 수 있다.
출 력 값
문 제 출 처
문제 링크 : www.acmicpc.net/problem/1504
1504번: 특정한 최단 경로
첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 ≤ N ≤ 800, 0 ≤ E ≤ 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존�
www.acmicpc.net