타임머신
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; }
핑백: 알고리즘 - 벨만-포드 (Bellman–Ford Algorithm) 알고리즘 정리 - 어제와 내일의 나 그 사이의 이야기