ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 9370, 삐빅-- 메모리 초괍니다(다익스트라로 최단경로 tree)
    백준 2022. 2. 4. 14:43
     

    9370번: 미확인 도착지

    (취익)B100 요원, 요란한 옷차림을 한 서커스 예술가 한 쌍이 한 도시의 거리들을 이동하고 있다. 너의 임무는 그들이 어디로 가고 있는지 알아내는 것이다. 우리가 알아낸 것은 그들이 s지점에서

    www.acmicpc.net

     

    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    #include <bits/stdc++.h>
    #define endl "\n" // don't use when you cover interactive problem
    #define ooop(i, n) for(int i = 0; i < n; i++)
    #define loop(i, n) for(int i = 1; i <= n; i++)
    #define all(v) (v).begin(), (v).end()
     
    using namespace std;
    typedef long long ll;
    typedef pair<intint> pi;
    typedef pair<ll, ll> pl;
    typedef tuple<intintint> ti;
     
    const int INF = 2e6;
    int n, m, t, start, g, h;
     
    void dijkstra(map<intvector<pi> >& edge, vector<int>& dp, map<intvector<int> >& shortest, int start)
    {
        priority_queue<ti, vector<ti>, greater<ti> > pq;
        pq.push({0, start, -1}); // weight, des, parent
        while(!pq.empty()){
            auto [dist, cur, parent] = pq.top(); pq.pop();
            // 각 노드에 대해 최초로 heap 에서 나올때가 최단경로
     
            if(dp[cur] < dist) continue;
            // 따라서 각 노드에 대해 이미 heap에서 나온적 있다면 dp[cur] 값은 이미 최단경로로 저장되었을 것
            shortest[parent].emplace_back(cur);
            if(dp[cur] == dist) continue;
            // 각 노드에 대해 dp[cur] 가 이미 최단경로라면 앞서 그 노드와 인접한 edge 는 rest 과정을 거쳤을 것이므로 생략
            dp[cur] = dist;
     
            for(auto [w, nex]: edge[cur]){
                int nex_dist = dist + w;
                if(nex_dist <= dp[nex]){ // < 가 아닌 등호까지 포함하므로써 가중치가 같은 최단경로 모두 구함
                    pq.push({nex_dist, nex, cur});
                }
            }
        }
    }
     
    void check(map<intbool>& des, int tar) // target 이 목적지 중 하나이면 방문표시
    {
        if(des.find(tar) != des.end()) des[tar] = true;
    }
     
    void bfs(map<intvector<int> >& shortest, map<intbool>& des, int start)
    {
        queue<int> q;
        q.push(start);
        check(des, start);
        while(!q.empty()){
            auto cur = q.front(); q.pop();
            for(auto nex: shortest[cur]){
                q.push(nex);
                check(des, nex);
            }
        }
    }
     
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0), cout.tie(0);
     
        int T; cin >> T;
        while(T--){
            cin >> n >> m >> t >> start >> g >> h;
            map<intvector<pi> > edge; // dep -> (weight, des)
            loop(i, m){
                int a, b, d; cin >> a >> b >> d;
                edge[a].emplace_back(d, b);
                edge[b].emplace_back(d, a);
            }
            map<intbool> des; // node -> isvisited?
            loop(i, t){
                int x; cin >> x;
                des[x] = false;
            }
     
            vector<int> dp(n+1, INF);
            map<intvector<int> > shortest; // 출발지로 각 노드를 방문하는 최단경로 tree
            dijkstra(edge, dp, shortest, start); // 다익스트라 알고리즘을 시행하면서 최단경로 tree 'shortest'를 만듬
     
     
            // shortest 를 bfs 로 순회하면서 목적지 des 가 나오면 방문표시
            if(find(all(shortest[g]), h) != shortest[g].end()) bfs(shortest, des, h);
            // shortest에서 g가 h의 parent 인 경우
            if(find(all(shortest[h]), g) != shortest[h].end()) bfs(shortest, des, g);
            // shortest에서 h가 g의 parent 인 경우
     
            for(auto [node, isvisited]: des){
                if(isvisited) cout << node << ' ';
            }
            cout << endl;
        }
     
        return 0;
    }
    cs

    '백준' 카테고리의 다른 글

    13549, Gold 5  (0) 2022.01.02
    2515, 골드 2  (0) 2021.11.11
    10999, Platinum 4  (0) 2021.10.08
    2042, Gold 1  (0) 2021.10.07
    16236, Gold 4  (0) 2021.10.03

    댓글

Designed by Tistory.