#문제

https://www.acmicpc.net/problem/1865

#작성 코드

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
#include <iostream>
#include <vector>
using namespace std;
 
int tc, n, m, w;
int INF = 987654321;
int s[501];        // s[i]로 가는 최단시간 저장 
vector<pair<int,int> > p[501];
bool flag;        // 음의 사이클 발생 여부 
 
int main(){
    cin>>tc;
    while(tc--){
        // 음의 사이클 발생여부, 도로, 웜홀 연결들, s배열을 초기화해준다. 
        flag = false;
        for(int i=0; i<501; i++)
            p[i].clear();
        fill_n(s, n, INF);
        s[1= 0;
        
        // 지점, 도로, 웜홀 개수 입력 
        cin>>n>>m>>w;
        // m개 도로 입력. 양방향. 
        for(int i=0; i<m; i++){
            int s, e, t;
            cin>>s>>e>>t;
            p[s].push_back(make_pair(e, t));
            p[e].push_back(make_pair(s, t));
        }
        // w개 웜홀 입력. 단방향. 음의 가중치.
        for(int i=0; i<w; i++){
            int s, e, t;
            cin>>s>>e>>t;
            p[s].push_back(make_pair(e, -t));
        }
        
        // 벨만 포드 알고리즘은 O(V*E)이다. 
        // 지점 개수 (V) 
        for(int i=1; i<=n; i++){
        // * 도로, 웜홀 개수(E) 
            for(int j=1; j<=n; j++){
                for(int k=0; k<p[j].size(); k++){
                    int next = p[j][k].first;
                    int cost = p[j][k].second;
                    if( s[j]!=INF && s[next]>cost+s[j]){
                        s[next] = cost + s[j];
                        if( i==n ){
                            // 음의 사이클 발생시 flag를 true로 한다. 
                            flag = true;
                        }
                    }
                }
            }
        }
        if(flag)
            cout<<"YES\n";
        else
            cout<<"NO\n";
    }
    return 0;
}
cs

 

travel 함수로 벨만포드 알고리즘을 분리한 코드.

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
#include <iostream>
#include <vector>
using namespace std;
 
vector<pair<int,int> > p[501];
int testcase, point, road, worm;
int time[501];
int INF = 2000000000;
 
bool travel(){
    for(int i=1; i<=point; i++){
        for(int j=1; j<=point; j++){
            for(int k=0; k<p[j].size(); k++){
                int next = p[j][k].first;
                int takes = p[j][k].second+time[j];
                
                if( time[j]!=INF && takes<time[next] ){
                    if( i==point ){
                        return true;
                    }
                    time[next] = takes;
                }
            }
        }
    }
    return false;
}
 
int main(){
    cin>>testcase;
    for(int tc=0; tc<testcase; tc++){
        // 1번 지점에서 각 지점으로 가는데 걸리는 시간 무한대로 초기화 
        for(int init=0; init<501; init++){
            time[init] = INF;
        }
        // 시작 지점에서 시작지점으로 가는 시간은 0이다. 
        time[1= 0;
        for(int i=0; i<501; i++){
            p[i].clear();
        }
        
        // 입력
        cin>>point>>road>>worm;
        for(int r=0; r<road; r++){
            int s, e, t;
            cin>>s>>e>>t;
            // 도로는 양방향(=무방향)이다. 
            p[s].push_back(make_pair(e, t));
            p[e].push_back(make_pair(s, t));
        }
        for(int w=0; w<worm; w++){
            int s, e, d;
            cin>>s>>e>>d;
            // 웜홀은 단방향이다.
            // 웜홀에서는 시간이 거꾸로 흐르므로 -d로 저장해준다. 
            p[s].push_back(make_pair(e, -d));
        }
        // 음의 사이클이 존재하면 yes
        // (음의 사이클 중 하나에서 출발하면 출발지로 돌아오면 과거가 된다.)
        if( travel() ) cout<<"YES\n";
        else cout<<"NO\n";
    }
    return 0;
}
cs

##

벨만포드 알고리즘 로직은 틀리지 않았는데, 자꾸 틀렸다는 판정을 받아서 원인을 찾기 힘들었다.

문제는 새로운 테스트케이스를 시작할 때 벡터p[]를 초기화해주지 않아서 이전 테스트케이스에서 입력받았던 도로, 웜홀 연결들이 남아있었기 때문이었다.

한 문제에 테스트케이스 여러 개를 입력받아서 실행한다면 매 테스트케이스마다 사용하는 변수, 배열들을 초기화해줘야 한다는 것을 잊지 말자!

'BOJ' 카테고리의 다른 글

BOJ 11404번 :: 플로이드  (0) 2019.12.20
BOJ 1541번 :: 잃어버린 괄호  (0) 2019.12.20
BOJ 11399번 :: ATM  (0) 2019.12.18
BOJ 1931번 :: 회의실 배정  (0) 2019.12.18
BOJ 11657번 :: 타임머신  (0) 2019.12.15

+ Recent posts