정리충의 정리노트

[백준] 9370: 미확인 도착지 본문

PS/ShortestPath

[백준] 9370: 미확인 도착지

ioqoo 2020. 3. 7. 18:57

0. 문제 주소

 

https://www.acmicpc.net/problem/9370

 

9370번: 미확인 도착지

문제 (취익)B100 요원, 요란한 옷차림을 한 서커스 예술가 한 쌍이 한 도시의 거리들을 이동하고 있다. 너의 임무는 그들이 어디로 가고 있는지 알아내는 것이다. 우리가 알아낸 것은 그들이 s지점에서 출발했다는 것, 그리고 목적지 후보들 중 하나가 그들의 목적지라는 것이다. 그들이 급한 상황이기 때문에 목적지까지 우회하지 않고 최단거리로 갈 것이라 확신한다. 이상이다. (취익) 어휴! (요란한 옷차림을 했을지도 모를) 듀오가 어디에도 보이지 않는다. 다

www.acmicpc.net

 

 

1. 풀이

 

[PS/ShortestPath] - [BOJ] 5719: 거의 최단 경로에서 썼던 테크닉을 쓴다.

 

S에서 다익스트라 알고리즘을 돌려 dist 배열을 만들고, 다른 모든 점에서 S로 거꾸로 거슬러 올라가며 거쳐가는 edge들이

 

최단 경로에 포함되는지를 체크해주면 된다. 그러다 (g, h)가 나오면 가능한 목적지, 끝까지 나오지 않는다면 불가능한 목적지이다.

 

 

2. 풀이 코드

 

* 유의할 점

 

 

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>

#define pii pair<int, int>
#define MAX 2005
#define INF 987654321

using namespace std;

int X, N, M, T;
int S, G, H;
int a, b, d;
vector<pii> graph[MAX];
vector<int> candi;
vector<int> ans;
int dist[MAX];
bool visited[MAX];

int main(){
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    #endif
    
    scanf("%d", &X);
    for (int x=0;x<X;x++){
        memset(visited, 0, sizeof(visited));
        candi.clear();
        ans.clear();
        fill(graph, graph+MAX, vector<pii> ());
        
        scanf("%d %d %d", &N, &M, &T);
        scanf("%d %d %d", &S, &G, &H);
        for (int i=0;i<M;i++){
            scanf("%d %d %d", &a, &b, &d);
            graph[a].push_back(pii(b, d));
            graph[b].push_back(pii(a, d));
        }
        int temp;
        for (int i=0;i<T;i++){
            scanf("%d", &temp);
            candi.push_back(temp);
        }
        sort(candi.begin(), candi.end());
        
        fill(dist, dist+MAX, INF);
        dist[S] = 0;
        priority_queue<pii, vector<pii>, greater<pii>> PQ;
        PQ.push(pii(0, S));
        while(!PQ.empty()){
            int curr = PQ.top().second, curr_dist = PQ.top().first;
            PQ.pop();
            if (visited[curr]) continue;
            visited[curr] = true;
            for (auto p: graph[curr]){
                int next = p.first, weight = p.second;
                if (dist[next] > curr_dist + weight){
                    dist[next] = curr_dist + weight;
                    PQ.push(pii(dist[next], next));
                }
            }
        }
        
        for (int n: candi){
            bool succ = false;
            memset(visited, 0, sizeof(visited));
            queue<int> Q;
            Q.push(n);
            while(!Q.empty()){
                int curr = Q.front();
                Q.pop();
                for (auto p: graph[curr]){
                    int next = p.first, weight = p.second;
                    if (dist[curr] - weight == dist[next]){
                        if ( (next == G && curr == H) || (next == H && curr == G) ){
                            succ = true;
                            break;
                        }
                        if (!visited[next]) {
                            Q.push(next);
                            visited[next] = true;
                        }
                    }
                }
                if (succ) {
                    ans.push_back(n);
                    break;
                }
            }
        }
        
        for (int n: ans){
            printf("%d ", n);
        }
        printf("\n");
        
        
    }
    
    

    return 0;
}

 

 

 

'PS > ShortestPath' 카테고리의 다른 글

[백준] 9323: 무임승차  (0) 2020.03.10
[백준] 2982: 국왕의 방문  (0) 2020.03.07
[백준] 2211: 네트워크 복구  (0) 2020.03.07
[백준] 5719: 거의 최단 경로 (수정)  (0) 2020.02.21
[백준] 3860: 할로윈 묘지  (0) 2020.02.21
Comments