본문 바로가기

PS

BOJ #1865 웜홀

문제 링크 : https://www.acmicpc.net/problem/1865

 

1865번: 웜홀

문제 때는 2020년, 백준이는 월드나라의 한 국민이다. 월드나라에는 N개의 지점이 있고 N개의 지점 사이에는 M개의 도로와 W개의 웜홀이 있다. (단 도로는 방향이 없으며 웜홀은 방향이 있다.) 웜홀

www.acmicpc.net

 

그래프의 경로 상에 음수 간선이 존재하는 벨만포드 알고리즘 입문 문제입니다.

 

별도의 트릭을 필요로 하지 않으며 벨만포드 알고리즘을 충실히 구현하면 됩니다.

 

벨만포드 알고리즘의 정의상, 정점의 개수(V) - 1회만큼 경로 갱신을 반복하면 전체 최단 경로들을 모두 구할 수 있습니다.

 

이후에 한번 더 인접 리스트를 통해 경로 갱신을 했을 때 최단 거리가 갱신되는 경우가 발생한다면,

 

해당 그래프는 무한히 최단 경로가 갱신되는 음의 cycle이 존재한다는 것을 알 수 있습니다.

 

cnt :: 최단 경로 갱신을 반복하는 횟수

updated :: V번째로 경로를 갱신할 때, 경로가 갱신된다면 음의 cycle이 존재

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <bits/stdc++.h>
using namespace std;
 
int t, n, m, w, dist[501];
vector <pair<intint>> vc[501];
 
int main() {
    scanf("%d"&t);
    while (t--) {
        scanf("%d%d%d"&n, &m, &w);
        for (int i = 1; i <= n; i++)
            dist[i] = 1e9, vc[i].clear();
        int a, b, c;
        for (int i = 1; i <= m; i++) {
            scanf("%d%d%d"&a, &b, &c);
            vc[a].push_back({ b, c });
            vc[b].push_back({ a, c });
        }
        for (int i = 1; i <= w; i++) {
            scanf("%d%d%d"&a, &b, &c);
            vc[a].push_back({ b, -c });
        }
        dist[1= 0;
        bool updated = true;
        int cnt = 0;
        while (updated && cnt != n) {
            updated = false;
            cnt++;
            for (int i = 1; i <= n; i++) {
                for (auto x : vc[i]) {
                    if (dist[x.first] > dist[i] + x.second) {
                        dist[x.first] = dist[i] + x.second;
                        updated = true;
                    }
                }
            }
        }
        if (cnt == n)
            printf("YES\n");
        else
            printf("NO\n");
    }
}
cs

'PS' 카테고리의 다른 글

BOJ #13907 세금  (0) 2020.08.03
BOJ #1857 발레리노  (0) 2020.08.01