728x90
반응형
1865번: 웜홀
문제
https://www.acmicpc.net/problem/1865
1865번: 웜홀
첫 번째 줄에는 테스트케이스의 개수 TC(1 ≤ TC ≤ 5)가 주어진다. 그리고 두 번째 줄부터 TC개의 테스트케이스가 차례로 주어지는데 각 테스트케이스의 첫 번째 줄에는 지점의 수 N(1 ≤ N ≤ 500),
www.acmicpc.net
풀이
어느 시작점에서 다시 시작 지점으로 돌아올 때 시간이 되돌아갈 수 있는지 여부를 구하는 문제다. 벨만 포드 알고리즘을 사용해 풀 수 있다.
도로는 양방향이지만 웜홀은 단방향임을 주의해야 한다.
처음엔 dist[1] < 0 이면 YES를 출력하도록 했다. 그러나 2%틀을 받고 모든 정점에서 다 해보는 코드를 짰는데 90% 언저리에서 시간초과가 났다. 결국 벨만 포드의 특성상 어느 정점에서 시작하던지 결과는 같게 나올 것이다. 그러므로 시작 정점이 어디든 어느 한 구간에서 음의 사이클이 생긴다면, 그중 한 정점이 우리가 원하는 한 정점이기 때문에 YES가 된다.
그리고 dist[j] != INF 라는 조건이 벨만-포드 알고리즘 안에 있었는데 이걸 제거하니 맞았다. 이유를 사실 잘 모르겠어서 누군가 아는 사람이 나타나 줬으면 좋겠다.
코드
#include <bits/stdc++.h>
using namespace std;
#define INF 1e9
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int T;
cin >> T;
while (T--) {
int N, M, W;
vector<pair<int, int>> graph[501];
vector<int> dist(501, INF);
bool minusCycle = false;
cin >> N >> M >> W;
while (M--) {
int s, e, t;
cin >> s >> e >> t;
graph[s].push_back({e, t});
graph[e].push_back({s, t});
}
while (W--) {
int s, e, t;
cin >> s >> e >> t;
graph[s].push_back({e, -t});
}
dist[1] = 0;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
for (auto &p : graph[j]) {
int next = p.first, d = p.second;
if (dist[next] > dist[j] + d) {
dist[next] = dist[j] + d;
if (i == N)
minusCycle = true;
}
}
cout << (minusCycle ? "YES\n" : "NO\n");
}
return 0;
}
728x90
반응형
'Problem Solving > BOJ' 카테고리의 다른 글
[백준 / BOJ] C++ 12851 숨바꼭질 2 (0) | 2023.02.23 |
---|---|
[백준 / BOJ] C++ 1697 숨바꼭질 (0) | 2023.02.23 |
[백준 / BOJ] C++ 11657 타임머신 (0) | 2023.02.22 |
[백준 / BOJ] C++ 1016 제곱 ㄴㄴ 수 (0) | 2023.02.21 |
[백준 / BOJ] C++ 9694 무엇을 아느냐가 아니라 누구를 아느냐가 문제다 (1) | 2023.02.21 |