티스토리 뷰

PS

[백준] 1738번 골목길 C++

Eastplanet 2022. 5. 10. 15:56

문제 출처: https://www.acmicpc.net/problem/1738

 

1738번: 골목길

첫째 줄에 골목길들이 교차하는 지점의 개수 n (2 ≤ n ≤ 100)과 골목길의 개수 m (1 ≤ m ≤ 20,000) 이 차례로 주어진다. 이어지는 m개의 행에 각각의 골목길을 나타내는 세 정수 u, v, w가 차례로

www.acmicpc.net

벨만 포드를 이용하여 가중치가 가장 경로를 출력해야 한다. 그러나 최적의 경로가 존재하지 않는 상황에서는 -1을 출력해야한다.

우선 경로를 알아내기 위해 값이 갱신 될 때 root[next] = j를 넣어주어 경로를 역추적 할 수 있도록 해주었다.

이 문제에서 곤란했던 부분은 어떤 상황에서 -1을 출력해야 하는지 생각하기가 어려웠다.

-1을 출력해야하는 경우들

1. 출발점에서 도착점까지 도착을 못하는경우

2. 사이클로부터 도착점에 도착할 수 있는 경우 (금품이 무한대가 되어 최적의 경로라는 것이 존재하지 않음)

--> 사이클이 존재하기만 하면 -1을 출력하도록 했었다. 사이클이 도착경로와 관계가 없는 경우에도 -1을 출력하는 문제가 있다. 따라서 사이클로 부터 도착점에 도착할 수 있는 경우는 금품이 무한대가 가능하기 때문에 -1이고

사이클로부터 도착점에 도착할 수 없는 경우 사이클 때문에 금품이 무한대가 되는 경우는 없기 때문에 경로를 출력하여 해결할 수 있다.

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
typedef pair<int, int>P;

vector<P> adj[101];
long long INF = -123456789123;

int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

    int N, M;
    cin >> N >> M;


    for (int i = 0; i < M; i++) {
        int a, b, d;
        cin >> a >> b >> d;
        adj[a].push_back(P(b, d));
    }

    long long dist[101];
    fill(dist, dist + 101, INF);

    int root[101];
    root[1] = -1;
    dist[1] = 0;
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            for (P p : adj[j]) {
                int next = p.first, d = p.second;
                if (dist[j] != INF && dist[next] < dist[j] + d) {
                    dist[next] = dist[j] + d;
                    root[next] = j;
                    if (i == N) { 
                        queue<int> q;
                        int visited[101] = { };
                        visited[j] = 1;
                        q.push(j);
                        while (!q.empty()) {
                            int curr = q.front(); q.pop();
                            for (P p : adj[curr]) {
                                if (visited[p.first] == 1)continue;
                                q.push(p.first);
                                visited[p.first] = 1;
                            }
                        }

                        if (visited[N]) {
                            cout << "-1";
                            return 0;
                        }
                    }
                }
            }
        }
    }
    if (dist[N] == INF) {
        cout << "-1"; return 0;
    }

   
   
    
    int prev = root[N];
    vector<int> temp;
    temp.push_back(N);
    while (true) {

        if (prev != -1) {
            temp.push_back(prev);
            prev = root[prev];
        }
        else break;
    }

    for (int i = temp.size() - 1; i >= 0; i--) {
        cout << temp[i] <<" ";
    }
        
}

 

'PS' 카테고리의 다른 글

[백준] 6593번 상범 빌딩 C++  (0) 2022.05.13
[백준] 11779번 최소비용 구하기 2 C++  (1) 2022.05.10
[백준] 11657번 타임머신 C++  (0) 2022.05.10
[백준] 4196 친구 네트워크  (0) 2022.04.27
[백준] 16562번 친구비  (0) 2022.04.27
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/01   »
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
글 보관함