ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 1738번 - 골목길
    알고리즘/백준 2024. 7. 6. 23:29

     

    문제

    1738번 골목길: https://www.acmicpc.net/problem/1738

    오랫만에 고통 좀 받은 문제, 얼른 풀고 SCC공부하려 했는데 시간 다 뺏김 ㅜㅜ

     

    양 또는 음의 가중치를 가지는 그래프에서 사이클을 판별하고 경로 추적을 하는 문제 (그래프, 벨만-포드)

    벨만 포드는 몰라서, SPFA로 품

     

     

     

    풀이

    1. 역방향 그래프를 생성해서 BFS를 돌려 해당 정점에서 N정점에 도달 가능한지 여부를 판단

    만약 해당 정점이 N정점에 도달하지 않는 정점이라면 1에서 N정점간의 비용을 구할 때 고려하지 않아도 된다. (사이클이 존재하지만 정답을 출력하는 경우!)

    2. SPFA 돌리기, SPFA 경로추적은 몰라서 그냥 다익스트라처럼 비슷하게 추적함

    if(check[nxt.n] == 0) continue; 와 같이 1번의 경우 고려X

    3. 스택으로 간선 출력

     

     

     

    코드

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cstring>
    #include <cmath>
    #include <unordered_map>
    #include <string>
    using namespace std;
    int N, M;
    int check[101];
    int visitedCnt[101];
    int visited[101];
    struct Node {
        int n, cost;
    };
    vector<Node> graph[101];
    vector<Node> rev[101];
    int answer[101];
    vector<int> path[101];
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int fg = 0;
        cin >> N >> M;
        for (int i = 0; i < M; ++i)
        {
            int a, b, c;
            cin >> a >> b >> c;
            if (a == b) fg = 1;
            graph[a].push_back({ b, -c });
            rev[b].push_back({ a, -c });
        }
    
        for (int i = 1; i <= N; ++i) answer[i] = 1987654321;
       
        // 역방향으로 각 노드가 도착점에 도달 가능한지 검사
        queue<int> q;
        q.push(N);
        check[N] = 1;
        while (!q.empty())
        {
            int now = q.front();
            q.pop();
            for (int i = 0; i < rev[now].size(); ++i)
            {
                Node nxt = rev[now][i];
                if (check[nxt.n]) continue;
                check[nxt.n] = 1;
                q.push(nxt.n);
            }
        }
        if (check[1] == 0) {
            //시작점이 도착점에 도달 불가한 경우
            cout << -1;
            return 0;
        }
    
        // SPFA
        q.push(1);
        answer[1] = 0;
        visited[1] = 1;
        while (!q.empty())
        {
            int now = q.front();
            q.pop();
            visitedCnt[now]++;
            visited[now] = 0;
            if (visitedCnt[now] >= N) {
                cout << -1;
                return 0;
            }
            for (int i = 0; i < graph[now].size(); ++i)
            {
                Node nxt = graph[now][i];
                int nxtCost = answer[now] + nxt.cost;
                if (check[nxt.n] == 0) continue;
                if (nxtCost > answer[nxt.n]) continue;
                else if (nxtCost == answer[nxt.n]) {
                    path[nxt.n].push_back(now);
                }
                else {
                    path[nxt.n].clear();
                    path[nxt.n].push_back(now);
                    answer[nxt.n] = nxtCost;
                    if (visited[nxt.n] == 0)
                    {
                        visited[nxt.n] = 1;
                        q.push(nxt.n);
                    }
                }
            }
        }
        
        stack<int> ans;
        for (int i = N; i != 1; i = path[i][0]) {        
            ans.push(i);
        }
        cout << "1 ";
    
        while (!ans.empty()) {
            cout << ans.top() << " ";
            ans.pop();
        }
        return 0;
    }

     

     

     

     

     

     

Designed by Tistory.