코딩 공부/백준

[백준][C++] 9370 미확인 도착지

김 정 환 2021. 3. 18. 22:59
반응형

www.acmicpc.net/problem/9370

 

9370번: 미확인 도착지

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

www.acmicpc.net

 

 

 

알고리즘 종류

    - 다익스트라

 

 

 

사고 과정

    - 아래와 같은 경우로 최단 거리 경로가 나올 수 있다. 그러면 하늘색 화살표마다 다익스트라 알고리즘을 적용한다. 첫 번째 경우로 예를 들면, S->G, H->E (G-H는 도로가 1개이다.)에서 경로들의 합을 구하고, S->E와 비교해서 같으면 된다.

 

    - 그런데 문제는 G와 H 중에 S와 가까운 노드는 무엇인가이다. S시작 다익스트라를 해보면, 2->1 VS 2->3 중에 노드 1까지 거리가 작으므로 가장 가까운 노드는 1이다. 이제 경우 2개에서 1개로 줄었다. 따라서 2->1 경로 비용을 구하고, 3->목적지까지 경로 비용을 구해서 더한 뒤에 2->목적지까지 경로 비용과 비교해서 같으면 우리가 찾는 목적지가 된다.

 

 

 

구현(C++)

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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <iostream>
#include <vector>
#include <cstring>
#include <queue>
#include <algorithm>
#define INF 987654321;
 
using namespace std
 
int T;
int n, m, t;
int s, g, h;
int mgCost;
 
vector<vector<pair<intint> > > edges;
vector<int> dests;
 
int S[2001];
int costs[2001];
 
void dijsktra(int start){
    
    priority_queue<pair<intint> > pq;
    pq.push({0, start});
    costs[start] = 0;
    
    while(!pq.empty()){
        int here = pq.top().second;
        int cost = -pq.top().first;
        pq.pop();
 
        if(cost > costs[here]) continue;
        for(int i=0; i<edges[here].size(); i++){
            int next = edges[here][i].first;
            int next_cost = cost + edges[here][i].second;
            
            if(next_cost < costs[next]){
                costs[next] = next_cost;
                pq.push({-next_cost, next});
            }
        }
    }
}
 
 
void solution(){
    // 출발점에서 G 또는 H로 이동  
    for(int i=0; i<=n; i++) costs[i] = INF;
    dijsktra(s);
    
    // 시작점과 가장 가까운 교차로 노드 찾기  
    int closeNode, farNode;
    
    if(costs[g] < costs[h]) {
        closeNode = g;
        farNode = h;
    }
    else{
        closeNode = h;
        farNode = g;
    } 
    
    // 출발 -> 최단 거리 경로 중에서 가장 가까운 교차 노드 
    int cost = costs[closeNode] + mgCost;
    
    // 가장 가까운 노드 G/H에서 도착지까지 이동  
    memcpy(S, costs, sizeof(costs));
    for(int i=0; i<=n; i++) costs[i] = INF;
    dijsktra(farNode);
    
    // 시작점 -> 도착점과 시작점 -> G/H -> 도착점 경로를 비교해서 같으면 도착점 넣어주기  
    vector<int> answer;
    for(int i=0; i<dests.size(); i++){
        int e = dests[i];
        if(S[e] == cost + costs[e]){
            answer.push_back(e);
        }
    }
    
    // 출력  
    sort(answer.begin(), answer.end());
    for(int i=0; i<answer.size(); i++cout << answer[i] << " ";
    cout << endl;
}
 
 
int main(void){
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    
    cin >> T;
    while(T--){
        
        cin >> n >> m >> t;
        cin >> s >> g >> h;
        
        edges.clear();
        dests.clear();
        edges.resize(n+1);
        
        int u, v, c;
        for(int i=0; i<m; i++){
            cin >> u >> v >> c;
            edges[u].push_back({v,c});
            edges[v].push_back({u,c});
            
            if(u==&& v==h) mgCost = c;
            else if(u==&& v==g) mgCost = c;
        }
        
        int e;
        for(int i=0; i<t; i++){
            cin >> e;
            dests.push_back(e);
        }
        
        solution();
    }
}
cs

 

 

 

시행착오

반응형

'코딩 공부 > 백준' 카테고리의 다른 글

[백준][C++] 18809 gaaaaaaaaaarden  (0) 2021.03.20
[백준][C++] 10217 KCM Travel  (0) 2021.03.19
[백준][C++] 1167 트리의 지름  (0) 2021.03.17
[백준][C++] 10711 모래성  (0) 2021.03.17
[백준][C++] 5014 스타트링크  (0) 2021.03.16