728x90
반응형
18223번: 민준이와 마산 그리고 건우
문제
https://www.acmicpc.net/problem/18223
18223번: 민준이와 마산 그리고 건우
입력의 첫 번째 줄에 정점의 개수 V와 간선의 개수 E, 그리고 건우가 위치한 정점 P가 주어진다. (2 ≤ V ≤ 5,000, 1 ≤ E ≤ 10,000, 1 ≤ P ≤ V) 두 번째 줄부터 E개의 줄에 걸쳐 각 간선의 정보
www.acmicpc.net
풀이
최단 경로 중에 민준이가 위치한 정점이 포함되는지 확인하는 문제다. 다익스트라 알고리즘으로 두 정점 간의 최단 경로를 구할 수 있다. 다익스트라 알고리즘에 대해 잘 모른다면 아래 링크를 통해 알아보자.
건우가 위치한 P 정점이 최단 경로 위에 있다면, (시작점부터 P까지의 거리 + P부터 도착점까지의 거리 = 시작점부터 도착점까지의 거리)를 만족해야 한다. 따라서 다익스트라를 총 세 번 사용해서 풀 수 있다.
코드
#include <bits/stdc++.h>
using namespace std;
#define INF 2147483647
int V, E, P;
vector<pair<int, int>> graph[5001]; // [정점][다음 정점, 거리]
vector<int> dist(5001, INF), visited(5001, 0);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
void init() {
for (int i = 1; i <= V; i++) {
visited[i] = 0;
dist[i] = INF;
}
}
int dijkstra(int s, int e) {
init(); // 배열 초기화
dist[s] = 0; // 시작점 거리 0
pq.push({0, s}); // 시작점만 pq에 추가
while (!pq.empty()) { // pq가 비면 종료
int curr;
do {
curr = pq.top().second;
pq.pop();
} while (!pq.empty() && visited[curr]); // curr이 방문한 정점이면 무시
// 더 이상 방문할 수 있는 정점이 없으면 종료
if (visited[curr])
break;
visited[curr] = 1; // 방문처리
for (auto &p : graph[curr]) {
int next = p.first, d = p.second;
// 거리가 갱신될 경우 pq에 추가
if (dist[next] > dist[curr] + d) {
dist[next] = dist[curr] + d;
pq.push({dist[next], next});
}
}
}
return dist[e];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> V >> E >> P;
// 간선
while (E--) {
int a, b, c;
cin >> a >> b >> c;
graph[a].push_back({b, c});
graph[b].push_back({a, c});
}
// 다익스트라
if (dijkstra(1, P) + dijkstra(P, V) == dijkstra(1, V))
cout << "SAVE HIM\n";
else
cout << "GOOD BYE\n";
return 0;
}
728x90
반응형
'Problem Solving > BOJ' 카테고리의 다른 글
[백준 / BOJ] C++ 27494 2023년은 검은 토끼의 해 (0) | 2023.02.20 |
---|---|
[백준 / BOJ] C++ 4485 녹색 옷 입은 애가 젤다지? (0) | 2023.02.20 |
[백준 / BOJ] C++ 17396 백도어 (0) | 2023.02.20 |
[백준 / BOJ] C++ 1963 소수 경로 (0) | 2023.02.20 |
[백준 / BOJ] C++ 2211 네트워크 복구 (0) | 2023.02.20 |