PS

BOJ 5719 - 거의 최단 경로

728x90

www.acmicpc.net/problem/5719

 

5719번: 거의 최단 경로

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 장소의 수 N (2 ≤ N ≤ 500)과 도로의 수 M (1 ≤ M ≤ 104)가 주어진다. 장소는 0부터 N-1번까지 번호가 매겨져 있

www.acmicpc.net

 

이 문제는 두번째 최단 경로를 구해야 하는 문제이다.

다익스트라 알고리즘을 사용하면, 가장 짧은 경로를 구할 수 있다.

그러나 이 문제는 그 다음번으로 짧은 경로를 찾아내야 한다.

이를 위해서, 다익스트라 알고리즘을 두 번 사용하되, 첫번째 다익스트라 알고리즘 수행하면서, 찾아낸 최단 경로들을 그래프 상에서 제거해야한다. 이를 위해 BFS 를 사용해서 최단경로에 해당하는 부분을 -1 로 만들어버리고, 다음 다익스트라 돌릴때, -1 인 부분은 제끼고 최단거리를 찾아내면 두번째 최단경로가 나타나게 된다.

 

참고 : www.crocus.co.kr/682

 

[5719번] 거의 최단 경로

문제 출처 : https://www.acmicpc.net/problem/5719 알고리즘 분석 : 문제 해결에 필요한 사항 1. 다익스트라 개념 :: http://www.crocus.co.kr/532 소스 코드 :: http://www.crocus.co.kr/533 2. 우선순위 큐를..

www.crocus.co.kr

 

 

- c++

#include <bits/stdc++.h>
 
#define MAX 501
#define INF 987654321
 
using namespace std;
 
int n, m;
vector<pair<intint>> adj[MAX];
vector<pair<intint>> shortest[MAX]; // 최단경로 저장할 벡터
bool visited[MAX][MAX]; // BFS 를 위한 배열 
 
vector<int> dijkstra(int start, int size) {
    vector<int> dist(size, INF);
    dist[start] = 0;
    
    priority_queue<pair<intint>> pq; // 비용, 노드 번호
    pq.push({0, start}); 
    
    while(!pq.empty()) {
        int cost = -pq.top().first;
        int cur =  pq.top().second;
        pq.pop();
        
        if (dist[cur] < cost) continue// 최단 거리가 아닐때
        
        for (int i = 0; i < adj[cur].size(); ++i) {
            int next = adj[cur][i].first;
            int next_dist = cost + adj[cur][i].second;
            
            if (adj[cur][i].second == -1continue// 삭제된 거리 제외 
            
            if (dist[next] > next_dist) { // 최단 거리 찾았을때 
                dist[next] = next_dist;
                pq.push({-next_dist, next}); // 음수로 넣어야 순서를 맞춤
                
                shortest[next].clear();
                shortest[next].push_back({cur, next_dist}); 
            } else if (dist[next] == next_dist) {
                shortest[next].push_back({cur, next_dist});
            }
        } 
    } 
    
    return dist;
 
void bfs(int dest) {
    queue<int> q;
    
    q.push(dest);
    
    while(!q.empty()) {
        int cur = q.front();
        q.pop();
        
        for (int i = 0; i < shortest[cur].size(); ++i) {
            int next = shortest[cur][i].first;
            if (visited[cur][next]) continue;
            
            visited[cur][next] = true;
            
            for (int j = 0; j < adj[next].size(); ++j) {
                if (adj[next][j].first == cur) {
                    adj[next][j].second = -1;
                }
            }
            
            q.push(next);
        }
    }
}
 
int main() {
    cin.tie(0); ios_base::sync_with_stdio(0);
    
    while(1) {
        cin >> n >> m;
        if (n == 0 && m == 0break;
        
        memset(shortest, 0sizeof(shortest));
        memset(visited, falsesizeof(visited));
        
        for (int i = 0; i < MAX; ++i) adj[i].clear();
        
        int start, dest;
        cin >> start >> dest;
        
        for (int i = 0; i < m; ++i) {
            int u, v, p;
            cin >> u >> v >> p;
            adj[u].push_back({v, p});
        }
        
        dijkstra(start, n); // 최단경로를 먼저 구함 
         
        bfs(dest); // 먼저 구한 최단경로를 지움 
        
        vector<int> result = dijkstra(start, n); // 최단경로가 아닌 값들을 찾아냄
        
        if (result[dest] == INF) cout << "-1\n";
        else cout << result[dest] << "\n"
    }
    
    return 0;
}
cs

 

 

728x90

'PS' 카테고리의 다른 글

BOJ 1941 - 소문난 칠공주  (0) 2021.01.31
BOJ 1328 - 고층 빌딩  (0) 2021.01.31
BOJ 10217 - KCM Travel  (0) 2021.01.31
BOJ 2812 - 크게 만들기  (0) 2021.01.24
BOJ 8983 - 사냥꾼  (0) 2021.01.24