타임머신
https://www.acmicpc.net/problem/11657
| 시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
|---|---|---|---|---|---|
| 1 초 | 256 MB | 48876 | 10037 | 6258 | 22.768% |
문제
N개의 도시가 있다.
그리고 한 도시에서 출발하여 다른 도시에 도착하는 버스가 M개 있다.
각 버스는 A, B, C로 나타낼 수 있는데, A는 시작도시, B는 도착도시, C는 버스를 타고 이동하는데 걸리는 시간이다.
시간 C가 양수가 아닌 경우가 있다.
C = 0인 경우는 순간 이동을 하는 경우, C < 0인 경우는 타임머신으로 시간을 되돌아가는 경우이다.
1번 도시에서 출발해서 나머지 도시로 가는 가장 빠른 시간을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 도시의 개수 N (1 ≤ N ≤ 500), 버스 노선의 개수 M (1 ≤ M ≤ 6,000)이 주어진다.
둘째 줄부터 M개의 줄에는 버스 노선의 정보 A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)가 주어진다.
출력
만약 1번 도시에서 출발해 어떤 도시로 가는 과정에서 시간을 무한히 오래 전으로 되돌릴 수 있다면 첫째 줄에 -1을 출력한다.
그렇지 않다면 N-1개 줄에 걸쳐 각 줄에 1번 도시에서 출발해 2번 도시, 3번 도시, …, N번 도시로 가는 가장 빠른 시간을 순서대로 출력한다.
만약 해당 도시로 가는 경로가 없다면 대신 -1을 출력한다.
예제 입력 1
3 4 1 2 4 1 3 3 2 3 -1 3 1 -2
예제 출력 1
4 3
예제 입력 2
3 4 1 2 4 1 3 3 2 3 -4 3 1 -2
예제 출력 2
-1
예제 입력 3
3 2 1 2 4 1 2 3
예제 출력 3
3 -1
출처
알고리즘 분류
풀이 과정

통과된 코드
#include <iostream>
#include <vector>
using namespace std;
constexpr long long int INF = INT64_MAX;
constexpr int MAXN = 501;
long long int disArr[MAXN];
bool check = false; // 음의 순환이 있는지 확인
// N : 도시의 개수, M : 버스 노선의 개수
// A : 시작 도시, B : 도착 도시, C : 걸리는 시간
int N, M, A, B, C;
vector<pair<int, int>> graph[MAXN];
int main()
{
ios_base::sync_with_stdio(false); // scanf와 동기화를 비활성화
// cin.tie(null); 코드는 cin과 cout의 묶음을 풀어줍니다.
cin.tie(NULL);
std::cout.tie(NULL);
cin >> N >> M;
for (int i = 0; i < M; i++) {
cin >> A >> B >> C;
// 단방향
graph[A].push_back(make_pair(B, C));
}
// 배열 초기화
fill(disArr, disArr + MAXN, INF);
disArr[1] = 0;
for (int k = 1; k <= N; k++) {// (모든 정점의 수 - 1) 번 확인한다.
// 모든 노선을 확인한다.
for (int i = 1; i <= N; i++) {
for (int j = 0; j < graph[i].size(); j++) {
int u = i; // 시작점
int v = graph[i][j].first; // 도착점
int weight = graph[i][j].second; // 가중치
// 만약 임시 배열이 무한대가 아니고 &&
// 시작 임시 배열의 가중치가 도착지의 가중치보다 작다면
if (disArr[u] != INF && disArr[u] + weight < disArr[v]) {
disArr[v] = disArr[u] + weight; // 임시배열을 업데이트 해준다.
// K가 N-1일때 모든 정점을 확인한 후
// K가 N일때 업데이트가 있다면 음의 순환이 있다는 이야기
if (k == N) {
cout << "-1";
return 0;
}
}
}
}
}
for (int i = 2; i <= N; i++) {
if (disArr[i] == INF) cout << "-1" << "\n";
else cout << disArr[i] << "\n";
}
return 0;
}


![백준 28074번 (모비스, C++) [BAEKJOON]](https://lycos7560.com/wp-content/uploads/boj-og.png)
![백준 1780번 (종이의 개수, C++, DivideAndConquer) [BAEKJOON]](https://lycos7560.com/wp-content/uploads/boj-og-1.png)
![백준 11724번 (연결 요소의 개수, C++, DFS) / 추가 반례 [BAEKJOON]](https://lycos7560.com/wp-content/uploads/2022/10/boj-og-1-2048x1070-1-1024x535.png)
핑백: 알고리즘 - 벨만-포드 (Bellman–Ford Algorithm) 알고리즘 정리 - 어제와 내일의 나 그 사이의 이야기