코딩스토리

백준 1238번 - 파티 본문

알고리즘/BOJ 문제 풀이

백준 1238번 - 파티

kimtaehyun98 2021. 2. 9. 22:11

www.acmicpc.net/problem/1238

 

1238번: 파티

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

www.acmicpc.net

 

다익스트라 알고리즘을 작년 8월에 처음 공부한 뒤

 

지금까지 한 번도 복습하지 않았다..

 

당연히 그때도 어려웠지만 지금은 완전히 까먹은 상태여서 언젠간 해야지 하다가 결국 어제오늘 복습을 했다.

 

 

사실 bfs 문제를 풀다가 '가중치'가 일정하지 않은 문제를 만나서 급하게 다익스트라를 공부한거긴 함ㅎㅎ

 

 

어쨌든

 

문제를 분석해보면

 

도로들은 단방향으로 이루어져있고 -> 단방향 그래프

 

각각의 도로들을 지나가는데에는 T[i] 만큼의 시간이 걸린다 -> 각 간선의 가중치 = T[i]

 

이 정도로 요약하고 그래프 문제로 모델링하면 쉽게 풀린다.

 

 

해결 방법은 다음과 같다.

 

1. 모든 노드에서 다익스트라 알고리즘을 통해 X(도착지점)까지의 최단거리를 구한 뒤 따로 저장해 놓는다.

2. X에서 다익스트라 알고리즘을 통해 다른 모든 노드들까지의 최단 거리를 구한다.

3. 위에서 구한 두 가지 정보를 합해서 최댓값을 찾는다.

 

주의해야 할 점은

 

사용하는 check배열, dis배열의 초기화이다.

 

문제에서 모든 학생들은 집에서 X에 갈 수 있고, X에서 집으로 돌아올 수 있는 데이터만 입력으로 주어진다고 하였으므로

도착하지 못하는 예외 케이스는 따로 처리하지 않아도 된다.

 

코드는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <queue>
#include <cstring>
#include <vector>
using namespace std;
 
int n, m, x, u, v, w;
bool check[1004];
vector<pair<intint>>g[1004];
int dis[1004];
 
void daijkstra(int start) {
    memset(dis, 127sizeof(dis));
    memset(check, falsesizeof(check));
    dis[start] = 0;
    priority_queue<pair<intint>vector<pair<intint>>, greater<pair<intint>> >pq;
    pq.push(make_pair(0, start));
    while (!pq.empty()) {
        int ver = pq.top().second;
        int wei = pq.top().first;
        pq.pop();
        if (check[ver] == true)continue;
        check[ver] = true;
        if (dis[ver] != wei)continue;
        for (int i = 0; i < g[ver].size(); i++) {
            int a = g[ver][i].second;
            int b = g[ver][i].first;
            if (dis[ver] + a < dis[b]) {
                dis[b] = dis[ver] + a;
                pq.push(make_pair(dis[b], b));
            }
        }
    }
}
 
int main() {
    cin >> n >> m >> x;
    for (int i = 0; i < m; i++) {
        cin >> u >> v >> w;
        g[u].push_back(make_pair(v, w));
    }
    vector<int>go(1004);
    for (int i = 1; i <= n; i++) {
        daijkstra(i);
        go[i] = dis[x];
    }
    daijkstra(x);
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        if (i == x)continue;
        ans = max(ans, go[i] + dis[i]);
    }
    cout << ans << "\n";
}
cs

 

 

Comments