본문 바로가기
백준일지

[백준] 달빛 여우 16118번

by 민지기il 2025. 3. 31.
#include <bits/stdc++.h>
#define fastio cin.tie(0)->sync_with_stdio(0)
#define INF 1e9
using namespace std;

int N,M, cnt;
vector<pair<int,int>> v[4001];
int dist[4001];
int dist2[4001][2];

void dijk(int start){
    for(int i=0; i<=N; i++) dist[i]=INF;
    dist[start] = 0;
    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;
    pq.push({0, start});
    while(!pq.empty()){
        int d = pq.top().first;
        int now = pq.top().second;
        pq.pop();
        if(dist[now] < d) continue;
        for(auto edge:v[now]){
            int next = edge.first;
            int cost = edge.second;
            if(dist[next] > dist[now] + cost){
                dist[next] = dist[now] + cost;
                pq.push({dist[next], next});
            }
        }
    }
}
void dijk2(int start){
    for(int i=0; i<=N; i++){
        dist2[i][0]=INF;
        dist2[i][1]=INF;
    }
    dist2[start][0] = 0;
    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq2;
    pq2.push({0,start,0});
    while(!pq2.empty()){
        auto[time,now,state] = pq2.top();
        pq2.pop();
        if(dist2[now][state] < time) continue;
        for(auto edge : v[now]){
            int next = edge.first;
            int cost = edge.second;
            
            int nextTime;
            if(state ==0){
                nextTime = time+cost/2;
                if(dist2[next][1] > nextTime){
                    dist2[next][1] = nextTime;
                    pq2.push({nextTime, next, 1});
                }
            }else{
                nextTime = time + cost*2;
                if(dist2[next][0]>nextTime){
                    dist2[next][0]=nextTime;
                    pq2.push({nextTime, next, 0});
                }
            }
        }
        
    }
}


int main(){
    fastio;
    cin>>N>>M;
    for(int i=0; i<M; i++){
        int a, b, c; cin>>a>>b>>c;
        v[a].push_back({b,c*2});
        v[b].push_back({a,c*2});
    }
    dijk(1);
    dijk2(1);
    int answer = 0;
    for(int i=2; i<=N; i++){
        int wolfTime = min(dist2[i][0], dist2[i][1]);
        if(dist[i]<wolfTime) answer++;
    }
    cout<<answer<<"\n";
    return 0;
}

<설명>

v[a].push_back({b,c*2})에서 c*2는 소수점 생성을 방지하기 위한 것

가중치의 합을 구하는 게 아니라 값을 비교하는 것이므로 곱해도 상관없음

tuple<int, int, int> → (시간, 현재 노드 번호, 상태)

auto [time, now, state] = pq2.top();를 통해 튜플의 각 요소를 한 줄에 변수로 분해해서 받는다

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

[백준] 1781번 컵라면  (0) 2025.04.03
[백준] 1450번 냅색문제  (0) 2025.04.02
[백준] 1766번 위상정렬  (0) 2025.03.31
[프로그래머스] 불량 사용자  (0) 2025.03.27
[프로그래머스] 등산코스 정하기  (0) 2025.03.26