※ 11657 타임머신
https://www.acmicpc.net/problem/11657
11657번: 타임머신
첫째 줄에 도시의 개수 N (1 ≤ N ≤ 500), 버스 노선의 개수 M (1 ≤ M ≤ 6,000)이 주어진다. 둘째 줄부터 M개의 줄에는 버스 노선의 정보 A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)가 주어진다.
www.acmicpc.net
#include <iostream>
#include <tuple>
#include <vector>
using namespace std;
typedef tuple<int, int, int> tp;
typedef long long ll;
const int INF = 5e6; //최대 n-1개의 간선을 지나게 됨 -> n * (가중치 최대값)
vector<ll> bellmanFord(int start, int n, int m, vector<tp> &edges) {
//최솟값 갱신하는 과정에서 언더플로우 일어날 수 있음
//500 * 6000 * (-10000) = -3e10 => int 범위 넘어감!
vector<ll> dist(n + 1, INF);
//시작 정점 초기화
dist[start] = 0;
for (int i = 1; i <= n; i++) {
bool flag = true; //더 이상 반복문을 실행할 필요가 없는지 확인 (갱신 확인)
for (int j = 0; j < m; j++) {
//s->d인 간선의 가중치가 w
int s = get<0>(edges[j]);
int d = get<1>(edges[j]);
int w = get<2>(edges[j]);
if (dist[s] == INF) { //아직 시작점에서 s로 가는 경로가 발견되지 않았으므로 갱신할 수 없음
continue;
}
ll next_weight = dist[s] + w;
if (next_weight < dist[d]) {
dist[d] = next_weight;
flag = false;
if (i == n) { //n번째 갱신이었다면 -> 음의 사이클
return {-1};
}
}
}
if (flag) { //더 이상 갱신되지 않았다면 더 탐색할 필요 없음
break;
}
}
return dist;
}
int main() {
int n, m, a, b, c;
//입력
cin >> n >> m;
vector<tp> edges(m); //간선 정보를 저장할 벡터
for (int i = 0; i < m; i++) {
cin >> a >> b >> c;
edges[i] = {a, b, c}; //방향 그래프
}
//연산
vector<ll> dist = bellmanFord(1, n, m, edges);
//출력
if (dist[0] == -1) { //음의 사이클
cout << "-1";
return 0;
}
for (int i = 2; i <= n; i++) {
cout << (dist[i] == INF ? -1 : dist[i]) << '\n';
}
return 0;
}
'C++' 카테고리의 다른 글
[Algorithm] 프로그래머스 합승택시-경유지포함 | C++ (0) | 2022.09.16 |
---|---|
[Algorithm] DP 백준 11057 오르막 수 | C++ (0) | 2022.09.09 |
[Algorithm] 플로이드-워셜 백준 11404 플로이드 | C++ (0) | 2022.09.09 |
[Algorithm] 다익스트라 백준 1753 최단경로 | C++ (0) | 2022.09.08 |
[Algorithm] BFS 백준 7576 토마토 | C++ (0) | 2022.09.08 |
댓글