최단거리 문제이다.
간선의 가중치가 음수인 케이스가 있으므로 다익스트라 알고리즘으로 풀 수 없고, 벨만포드 알고리즘으로 풀어야 한다.
노드가 n개일 때, 최대 n-1개의 간선에 대하여 최단거리를 계산해준다.
따라서 시간복잡도는 n개의 노드에 대해서 n-1개의 간선을 검사하므로 O(V*E) = O(V^3)이 나온다.
다만 음수사이클이 있는 경우를 계산하기 위해서 n번째 노드까지 검사를 했을 때 최단거리가 변경되는 경우를 체크해준다.
처음에 최단거리 벡터를 int 타입으로 선언해줬는데 이로 인해서 출력초과 에러가 났다. 음수 사이클이 생기는 경우에 int 범위를 벗어나는 underflow가 생겨서 그렇다.
www.acmicpc.net/board/view/55270
#include <iostream>
#include <vector>
using namespace std;
#define INF 987654321
// shortest path - bellman-ford's algorithm
// 노드가 n개일 때 n-1개의 간선을 검사해서 최단거리를 구함
struct Edge {
int from, to, weight;
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, m; // 도시500, 노선6000
cin >> n >> m;
vector<Edge> edge(m); // 간선리스트
vector<long long> dist(n + 1, INF); // 시작점부터 i까지 가는 최단경로
for (int i = 0; i < m; ++i) {
int from, to, weight;
cin >> from >> to >> weight;
edge[i] = {from, to, weight};
}
dist[1] = 0;
bool negative_cycle = false;
for (int i = 1; i <= n; ++i) { // 간선에 대해서 n-1번 검사, n번째에서 음수사이클 검사
for (int j = 0; j < m; ++j) { // 마을i로부터 나머지 마을까지의 최단경로를 모두 계산
const auto& [x, y, w] = edge[j];
if (dist[x] != INF && dist[y] > dist[x] + w) {
dist[y] = dist[x] + w;
if (i == n) {
negative_cycle = true;
}
}
}
}
if (negative_cycle) {
cout << -1;
return 0;
}
for (int i = 2; i <= n; ++i) {
if (dist[i] == INF) dist[i] = -1;
cout << dist[i] << '\n';
}
return 0;
}
'Algorithm > BOJ' 카테고리의 다른 글
8980 - 택배(greedy) (0) | 2021.04.01 |
---|---|
[boj]15723 - n단논법(Floyd Warshall, string 입출력) (0) | 2021.04.01 |
[boj] 8980 - 택배(greedy) (0) | 2021.03.29 |
boj 1197 - 최소 스패닝 트리(MST, kruskal) (0) | 2021.03.28 |
1922- 네트워크 연결 C++(MST, prim or kruskal, BFS) (0) | 2021.03.28 |