article thumbnail image
Published 2022. 1. 11. 23:46

문제 설명

문제 링크

http://icpc.me/1238

 

1238번: 파티

첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 10,000), X가 공백으로 구분되어 입력된다. 두 번째 줄부터 M+1번째 줄까지 i번째 도로의 시작점, 끝점, 그리고 이 도로를 지나는데 필요한 소요시간 Ti가 들어

www.acmicpc.net

풀이

다익스트라를 이용하여 풀 수 있다.

모든 점에 대해서 다익스트라를 돌려서 O(M^2logN)에도 풀 수 있지만, 관점을 약간 틀면 더 O(MlogN)에 풀 수 있다.

단방향 도로이기 때문에 순방향으로 x를 시작점으로 돌린다면 마을로 돌아가는 최간거리를 구할 수 있다.

그리고 역방향그래프를 x를 시작점으로 돌린다면 x까지 가는 최단거리를 구할 수 있다.

코드

#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;

const int N = 1003;
const int INF = 1e8;
vector<pii> adj1[N];
vector<pii> adj2[N];
int n, m, x; 
int dist1[N];
int dist2[N];

void dijkstra(vector<pii> v[], int dist[]) {
    priority_queue<pii, vector<pii>, greater<>> pq;
    fill(dist, dist + N, INF);
    pq.push({0, x});
    dist[x] = 0;
    while (!pq.empty()) {
        int cur = pq.top().second;
        pq.pop();
        for (auto [nxt, d] : v[cur]) {
            if (dist[cur] + d < dist[nxt]) {
                dist[nxt] = dist[cur] + d;
                pq.push({dist[nxt], nxt});
            }
        }
    }
}

int main() {
    scanf("%d %d %d", &n, &m, &x);
    for (int i = 0; i < m; i++) {
        int a, b, c; scanf("%d %d %d", &a, &b, &c);
        adj1[a].push_back({b, c});
        adj2[b].push_back({a, c});
    }
    dijkstra(adj1, dist1);
    dijkstra(adj2, dist2);      
    int ans = 0;
    for (int i = 1; i <= n; i++) ans = max(ans, dist1[i] + dist2[i]);
    printf("%d", ans);
}

'Algorithm > BOJ' 카테고리의 다른 글

백준[1865] 웜홀  (0) 2022.01.18
백준[7662] 이중 우선순위 큐  (0) 2022.01.14
백준[1562] 계단 수  (0) 2022.01.09
백준[1208] 부분수열의 합 2  (0) 2022.01.09
백준[6086] 최대 유량  (0) 2021.12.27
복사했습니다!