알고리즘 풀이/수학

BOJ 11657 [타임머신]

갓우태 2021. 3. 19. 22:50

BOJ 11657 : 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

처음에 queue에 넣어서 bfs처럼 풀어보려고 시도했으나, cycle을 알아낼 마땅한 방법이 떠오르지 않아 재귀 형식으로 바꿨다.

 

key point는 재귀함수 내의 if문이다.

  • 현재 재귀호출하면서 방문한 적 없는가?
  • 현재 재귀 내에서 방문한 적이 없더라도, 이전에 방문했을 때 저장된 값(arr)보다 적은 시간이 걸리는가?

이 두가지를 따져가며 풀 수 있었다.

 

 

 

 

먼저 1을 방문한다. 1의 다음 도시는 2, 3인데 2부터 방문해본다.

 

방문한 적 없으니 2로 들어가되, 현재 도달한 시간이 저장된 값보다 작으므로 업데이트한다.

 

3도 방문한 적 없으니 방문체크 하고, 저장된 값보다 작으므로 업데이트한다.

 

현재 가지에서 1을 방문한 적이 있다. 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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
#include <vector>
#include <limits.h>
using namespace std;
 
int arr[501];
bool visited[501];
 
struct City {
public:
    int destination, distance;
};
vector<vector<City>> cities;
 
int result = 0;
void recursive(int current) {
    for (City c : cities[current]) {
        int next = c.destination;
        int dist = c.distance;
        if (!visited[next]) {
            visited[next] = true;
            
            if (arr[next] > arr[current] + dist) {
                arr[next] = arr[current] + dist;
                dfs(next);
            }
            visited[next] = false;
        }
        else {
            if (arr[next] > arr[current] + dist) {
                result = -1;
                return;
            }
        }
    }
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
 
    int N, M;
    cin >> N >> M;
    
    cities.resize(N + 1);
    fill_n(arr, N + 1, INT_MAX);
    arr[1= 0;
    for (int busIdx = 0; busIdx < M; busIdx++) {
        
        int A, B, C;
        cin >> A >> B >> C;
        City city;
        city.destination = B;
        city.distance = C;
        cities[A].push_back(city);
    }
    visited[1= true;
    
    dfs(1);
    
    if (result == -1) {
        cout << result << "\n";
    }
    else {
        for (int i = 2; i <= N; i++) {
            if (arr[i] == INT_MAX) {
                cout << "-1\n";
            }
            else {
                cout << arr[i] << "\n";
            }
        }
    }
    return 0;
}
cs
반응형