algorithm

BOJ 1238

rkawk 2022. 9. 17. 14:33
더보기

νŒŒν‹° μ„±κ³΅λ‹€κ΅­μ–΄

ν•œκ΅­μ–΄   

 

1 초 128 MB 29692 14648 9730 47.454%

문제

N개의 숫자둜 κ΅¬λΆ„λœ 각각의 λ§ˆμ„μ— ν•œ λͺ…μ˜ 학생이 μ‚΄κ³  μžˆλ‹€.

μ–΄λŠ λ‚  이 Nλͺ…μ˜ 학생이 X (1 ≤ X ≤ N)번 λ§ˆμ„μ— λͺ¨μ—¬μ„œ νŒŒν‹°λ₯Ό 벌이기둜 ν–ˆλ‹€. 이 λ§ˆμ„ μ‚¬μ΄μ—λŠ” 총 M개의 단방ν–₯ λ„λ‘œλ“€μ΄ 있고 i번째 길을 μ§€λ‚˜λŠ”λ° Ti(1 ≤ Ti ≤ 100)의 μ‹œκ°„μ„ μ†ŒλΉ„ν•œλ‹€.

각각의 학생듀은 νŒŒν‹°μ— μ°Έμ„ν•˜κΈ° μœ„ν•΄ κ±Έμ–΄κ°€μ„œ λ‹€μ‹œ κ·Έλ“€μ˜ λ§ˆμ„λ‘œ λŒμ•„μ™€μ•Ό ν•œλ‹€. ν•˜μ§€λ§Œ 이 학생듀은 μ›Œλ‚™ κ²Œμ„λŸ¬μ„œ μ΅œλ‹¨ μ‹œκ°„μ— 였고 κ°€κΈ°λ₯Ό μ›ν•œλ‹€.

이 λ„λ‘œλ“€μ€ 단방ν–₯이기 λ•Œλ¬Έμ— μ•„λ§ˆ 그듀이 였고 κ°€λŠ” 길이 λ‹€λ₯Όμ§€λ„ λͺ¨λ₯Έλ‹€. Nλͺ…μ˜ 학생듀 쀑 였고 κ°€λŠ”λ° κ°€μž₯ λ§Žμ€ μ‹œκ°„μ„ μ†ŒλΉ„ν•˜λŠ” 학생은 λˆ„κ΅¬μΌμ§€ κ΅¬ν•˜μ—¬λΌ.

μž…λ ₯

첫째 쀄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 10,000), Xκ°€ 곡백으둜 κ΅¬λΆ„λ˜μ–΄ μž…λ ₯λœλ‹€. 두 번째 쀄뢀터 M+1번째 μ€„κΉŒμ§€ i번째 λ„λ‘œμ˜ μ‹œμž‘μ , 끝점, 그리고 이 λ„λ‘œλ₯Ό μ§€λ‚˜λŠ”λ° ν•„μš”ν•œ μ†Œμš”μ‹œκ°„ Tiκ°€ λ“€μ–΄μ˜¨λ‹€. μ‹œμž‘μ κ³Ό 끝점이 같은 λ„λ‘œλŠ” μ—†μœΌλ©°, μ‹œμž‘μ κ³Ό ν•œ λ„μ‹œ Aμ—μ„œ λ‹€λ₯Έ λ„μ‹œ B둜 κ°€λŠ” λ„λ‘œμ˜ κ°œμˆ˜λŠ” μ΅œλŒ€ 1κ°œμ΄λ‹€.

λͺ¨λ“  학생듀은 μ§‘μ—μ„œ X에 갈수 있고, Xμ—μ„œ μ§‘μœΌλ‘œ λŒμ•„μ˜¬ 수 μžˆλŠ” λ°μ΄ν„°λ§Œ μž…λ ₯으둜 μ£Όμ–΄μ§„λ‹€.

좜λ ₯

첫 번째 쀄에 Nλͺ…μ˜ 학생듀 쀑 였고 κ°€λŠ”λ° κ°€μž₯ 였래 κ±Έλ¦¬λŠ” ν•™μƒμ˜ μ†Œμš”μ‹œκ°„μ„ 좜λ ₯ν•œλ‹€.

예제 μž…λ ₯ 1 λ³΅μ‚¬

4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3

예제 좜λ ₯ 1 λ³΅μ‚¬

10​

λ…Έλ“œμ˜ κ°œμˆ˜κ°€ 1000개라 ν”Œλ‘œμ΄λ“œλ„ ν•œλ²ˆ ν•΄λ΄€λŠ”λ° μ—­μ‹œ μ‹œκ°„μ΄ˆκ³Όλ‹€. μ˜μ‹¬ν•  것 μ—†μ§€ 10^9 κ°€κΉŒμ›Œμ§€λ©΄ λ°”λ‘œ λœ¬λ‹€.

N개의 λ…Έλ“œμ—μ„œ λ‹€μ΅μŠ€νŠΈλΌλ₯Ό 돌리고, X번째 λ…Έλ“œμ—μ„œ λ‹€μ΅μŠ€νŠΈλΌλ₯Ό λŒλ¦¬λ‹ˆ

N                        *                            (N-1)                 +             log E

전체λ₯Ό λ‹€ λŒλ €μ£Όμ–΄μ•Ό ν•˜λ‹ˆ                 N개의 λ…Έλ“œ                pqμ‘μš©ν•œ κ°„μ„  뽑기

μ •λ„μ˜ μ‹œκ°„μ΄ λ‚˜μ™€, 1000^2 log 10000 μ •λ„λ‘œ μ•ˆμ •μ μ΄λ‹€.

 

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 987654321
using namespace std;

int N, M, X, ans;
vector<vector<pair<int,int>>>graph(1001);

vector<int> dstra(int start){
    vector<int>dist(1001,INF);
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>>pq;
    dist[start] = 0;
    pq.push({0,start});
    while(!pq.empty()){
        int cur_node = pq.top().second;
        int cur_dist = pq.top().first;
        pq.pop();
        for(auto node : graph[cur_node]){
            int nxt_node = node.second;
            int nxt_dist = node.first + cur_dist;
            if(dist[nxt_node] > nxt_dist){
                dist[nxt_node] = nxt_dist;
                pq.push({nxt_dist, nxt_node});
            }
        }
    }
    return dist;

}
int dstra2(int start){
    vector<int>dist(1001,INF);
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>>pq;
    dist[start] = 0;
    pq.push({0,start});
    while(!pq.empty()){
        int cur_node = pq.top().second;
        int cur_dist = pq.top().first;
        pq.pop();
        for(auto node : graph[cur_node]){
            int nxt_node = node.second;
            int nxt_dist = node.first + cur_dist;
            if(dist[nxt_node] > nxt_dist){
                dist[nxt_node] = nxt_dist;
                pq.push({nxt_dist, nxt_node});
            }
        }
    }
    return dist[X];
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin>>N>>M>>X;
    for(int i=0; i<M; i++){
        int a, b, c;
        cin>>a>>b>>c;
        graph[a].push_back({c,b});
    }
    for(int i=0; i<graph.size(); i++)
        sort(graph[i].begin(), graph[i].end());

    vector<int>x_dist = dstra(X);
    
    for(int i=1; i<=N; i++){
        if(i == X) continue;
        ans = max(ans, x_dist[i]+dstra2(i));
    }
    cout<<ans;


}