[백준] 11657번: 타임머신
[백준] 11657번: 타임머신
📌 문제
https://www.acmicpc.net/problem/11657
📌 설명
음의 가중치를 가지는 간선에서 최단 경로를 구하는 문제이므로 다익스트라는 사용할 수 없으며, 벨만-포드나 플로이드-워셜 알고리즘을 사용해야 한다. 단, 몇 가지 고려해야 하는 점이 있다.
먼저 출발지와 도착지가 같은 버스가 여러 개 존재할 수 있다. 이는 예제 입력 3에 나와있으며, 단순히 입력을 받을 때 가중치가 작은 값으로 계속 초기화시켜주면 된다.
두 번째는 만약 1번 도시에서 출발해 어떤 도시로 가는 과정에서 시간을 무한히 오래 전으로 되돌릴 수 있다면 첫째 줄에 -1을 출력한다. 라는 부분이다. 이는 최단 거리 배열(dist)에서 음의 사이클이 존재하고, 출발지(1)에서 접근할 수 있는 경우이다. 구체적으로 표현하면, dist[i][i] < 0이고 dist[1][i]의 경로가 존재한다면 -1을 출력하고 종료해야 한다.
마지막으로 삼중 for문을 통해 dist배열을 초기화할 때, 출발 노드에서 중간 노드 또는 중간 노드에서 도착 노드까지의 경로가 존재하지 않는다면 dist를 초기화할 수 없다.
위 사항들을 참고하여 코드를 작성해야 한다.
📌 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
#include <algorithm>
#define MAX_INF 6e7+1
using namespace std;
int arr[501][501];
int dist[501][501];
int main() {
cin.tie(0);
ios::sync_with_stdio(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
arr[i][j] = MAX_INF;
}
}
for (int i = 0; i < m; i++) {
int s, e, c;
cin >> s >> e >> c;
arr[s][e] = min(arr[s][e], c);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j)
dist[i][j] = min(dist[i][j], 0);
else if (arr[i][j])
dist[i][j] = arr[i][j];
}
}
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (dist[i][k] == MAX_INF || dist[k][j] == MAX_INF)
continue;
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
// i에서 음의 사이클이 발생하고 1에서 도달할 수 있는 경우
for (int i = 1; i <= n; i++) {
if (dist[i][i] < 0) {
if (dist[1][i] != MAX_INF) {
cout << -1;
return 0;
}
}
}
for (int i = 2; i <= n; i++) {
if (dist[1][i] == MAX_INF) {
cout << -1 << "\n";
}
else
cout << dist[1][i] << "\n";
}
}
This post is licensed under CC BY 4.0 by the author.