티스토리 뷰

w에 -1을 곱해 최단 경로를 구하는 문제로 바꾼다.

벨만포드로 그래프를 순회하고 사이클이 있는 지 확인한다.

출발지에서 사이클로 갈 수 있고, 사이클에서 도착지로 갈 수 있다면 무한루프가 발생해 답은 -1이 된다.

벨만포드로 출발지에서 사이클로 갈 수 있는 지 알 수 있고,

역방향 BFS로 사이클에서 도착지로 갈 수 있는 지를 알 수 있다.

무한루프가 발생하지 않는다면 경로복원으로 경로를 찾아 출력한다.

 

#include <bits/stdc++.h>
#define ll long long
#define X first
#define Y second
#define fastio ios::sync_with_stdio(0), cin.tie(0);
using namespace std;

vector<vector<pair<ll,ll> > > edges;
vector<vector<int> > back_edges;
int visited[101];
ll dist[101];
int where[101];

int main() {
    fastio;
    int V, E;
    cin >> V >> E;
    edges.resize(V + 1);
    back_edges.resize(V + 1);
    fill(dist, dist + V + 1, 0x7f7f7f7f);
    while (E--) {
        int u, v, w;
        cin >> u >> v >> w;
        edges[u].push_back({-w, v});
        back_edges[v].push_back(u);
    }
    dist[1] = 0;
    for (int tc = 0; tc < V - 1; tc++) {
        for (int i = 1; i <= V; i++) {
            if (dist[i] == 0x7f7f7f7f) continue;
            for (const auto &[w,e]: edges[i]) {
                if (dist[e] > dist[i] + w) {
                    dist[e] = dist[i] + w;
                    where[e] = i;
                }
            }
        }
    }
    for (int i = 1; i <= V; i++) {
        if (dist[i] == 0x7f7f7f7f || dist[i] == 0x8f8f8f8f) continue;
        for (const auto &[w,e]: edges[i]) {
            if (dist[e] > dist[i] + w) {
                dist[e] = 0x8f8f8f8f;
            }
        }
    }
    if (dist[V] == 0x7f7f7f7f || dist[V] == 0x8f8f8f8f) {
        cout << -1;
        return 0;
    }
    queue<int> q;
    q.push(V);
    visited[V] = true;
    while (!q.empty()) {
        int tmp = q.front();
        q.pop();
        for (int it: back_edges[tmp]) {
            if (!visited[it]) {
                if (dist[it] == 0x8f8f8f8f) {
                    cout << -1;
                    return 0;
                }
                visited[it] = true;
                q.push(it);
            }
        }
    }
    where[1] = -1;
    vector<int> out;
    int cur = V;
    while (cur != -1) {
        out.push_back(cur);
        cur = where[cur];
    }
    for (int i = (int) out.size() - 1; i >= 0; i--) {
        cout << out[i] << " ";
    }

    return 0;
}

 

'알고리즘 문제 풀이' 카테고리의 다른 글

백준 2104, 6549 C++ 풀이  (0) 2024.08.23
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/06   »
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
글 보관함