문제링크 : https://www.acmicpc.net/problem/1238
1238번: 파티
첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 10,000), X가 공백으로 구분되어 입력된다. 두 번째 줄부터 M+1번째 줄까지 i번째 도로의 시작점, 끝점, 그리고 이 도로를 지나는데 필요한 소요시간 Ti가 들어
www.acmicpc.net
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAX = 987654321;
int N, M, X, result;
int dist[2][1001];
vector<pii>v[2][1001];
void Dijkstra(int d, int s)
{
priority_queue<pii, vector<pii>, greater<pii>> pq; //비용이 적은순으로
pq.push({0, s});
dist[d][s] = 0; //시작
while(!pq.empty())
{
auto [cost, cur] = pq.top();
pq.pop();
if(dist[d][cur] < cost) continue;
for(int i=0; i<v[d][cur].size(); i++)
{
int next = v[d][cur][i].first; //다음 위치
int ncost = cost + v[d][cur][i].second; //다음 비용
if(dist[d][next] > ncost) //비용 갱신
{
dist[d][next] = ncost;
pq.push({ncost, next});
}
}
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M >> X;
for(int i=0; i<M; i++)
{
int a, b, c;
cin >> a >> b >> c; //시작, 끝, 비용
v[0][a].push_back({b, c}); //정방향
v[1][b].push_back({a, c}); //역방향
}
for(int i=1; i<=N; i++)
{
dist[0][i] = MAX;
dist[1][i] = MAX;
}
Dijkstra(0, X); //시작점 ~ X
Dijkstra(1, X); //X ~ 시작점
for(int i=1; i<=N; i++)
{
result = max(result, dist[0][i] + dist[1][i]); //갔다 온 거리중 최대값 저장
}
cout << result;
return 0;
}
기본적인 다익스트라에서 조금 응용된 문제이다.
일반적인 다익스트라에서는 목표 지점까지의 총 비용을 구했지만, 해당 문제는 목표 지점에 도착하고 다시 시작점으로 돌아오는 것까지 계산해주어야 한다.
이를 위해 처음 간선을 입력받는데 정방향으로 1개, 역방향으로 1개씩 값을 저장해준다.
이후 시작점 ~ X까지의 다익스트라 탐색 1번
X ~ 시작점까지의 다익스트라 탐색 1번 돌려주고, 각 탐색했을 때 든 비용을 저장한 배열에서 최대값을 찾아주면 된다.
'백준 > 골드' 카테고리의 다른 글
[백준 27172번] 수 나누기 게임 (C++) (0) | 2023.08.23 |
---|---|
[백준 2638번] 치즈 (C++) (0) | 2023.08.22 |
[백준 1197번] 최소 스패닝 트리 (C++) (0) | 2023.08.20 |
[백준 11779번] 최소비용 구하기 2 (C++) (0) | 2023.08.19 |
[백준 1918번] 후위 표기식 (C++) (0) | 2023.08.18 |