[BOJ] 오민식의 고민
Date:
[BOJ] 오민식의 고민
Problem URL : 오민식의 고민
#include <vector>
#include <queue>
#include <iostream>
#define p pair<int,int>
#define INF 987654321
using namespace std;
vector<p> edge[101];
long long dist[101];
int n, m, start, finish, earning[101];
bool visited[100] = { false, };
queue<int> negativeCycleNode;
void bellman() {
for (int i = 1; i <= n - 1; i++) {
bool updated = false;
for (int node = 0; node < n; node++) {
for (int nth = 0; nth < edge[node].size(); nth++) {
if (dist[node] == INF) continue;
int to = edge[node][nth].first;
int cost = edge[node][nth].second;
// 돈을 버는 것은 비용이 드는 개념의 -로 생각할 수 있다.
// 그래서 earning에 -를 붙여주자
long long newDist = dist[node] + cost - earning[to];
if (dist[to] > newDist) {
dist[to] = newDist;
updated = true;
}
}
}
if (!updated) {
// 갱신이 안되었으면 조기종료
return;
}
}
// 음수 싸이클 확인 과정
for (int node = 0; node < n; node++) {
for (int nth = 0; nth < edge[node].size(); nth++) {
if (dist[node] == INF) continue;
int to = edge[node][nth].first;
int cost = edge[node][nth].second;
long long newDist = dist[node] + cost - earning[to];
if (dist[to] > newDist) {
dist[to] = newDist;
visited[node] = true;
// 음수 싸이클 노드를 모아준다.
negativeCycleNode.push(node);
}
}
}
}
// 음수 싸이클 노드로부터 finish(도착점)까지 이동할 수 있는지 확인
bool isGee() {
while (!negativeCycleNode.empty()) {
int cur = negativeCycleNode.front();
negativeCycleNode.pop();
for (int i = 0; i < edge[cur].size(); i++) {
int next = edge[cur][i].first;
if (visited[next]) continue;
visited[next] = true;
negativeCycleNode.push(next);
}
if (visited[finish]) {
return true;
}
}
return false;
}
int main() {
int from, to, cost;
scanf("%d %d %d %d", &n, &start, &finish, &m);
for (int i = 0; i < m; i++) {
scanf("%d %d %d", &from, &to, &cost);
edge[from].push_back({ to, cost });
}
for (int i = 0; i < n; i++) {
scanf("%d", earning + i);
}
fill(dist, dist + n, INF);
dist[start] = -earning[start];
bellman();
if (dist[finish] == INF) {
printf("gg\n");
} else {
if (isGee()) {
printf("Gee\n");
} else {
printf("%lld\n", -dist[finish]);
}
}
return 0;
}
Comments
벨만 포드 알고리즘
각 노드에서 돈을 버는 개념을 -해준 후, 간선에서 드는 비용에 더해주는 게 포인트
벨만 포드 조기 종료 조건과 음수 싸이클 확인 과정을 잘 기억해두자
댓글