Henu
개발냥발
Henu
전체 방문자
오늘
어제
  • 분류 전체보기 (411)
    • DevOps (52)
      • Kubernetes (19)
      • Docker (14)
      • AWS (3)
      • Nginx (4)
      • Linux (4)
      • ArgoCD (1)
      • CN (2)
      • NATS (0)
      • Git (5)
    • Back-End (30)
      • Django (18)
      • Spring (5)
      • JPA (1)
      • MSA (5)
    • CS (87)
      • SystemSoftware (20)
      • OS (25)
      • Computer Architecture (16)
      • Network (23)
      • Database (2)
    • Lang (21)
      • Java (9)
      • Python (4)
      • C# (8)
    • Life (12)
    • 블록체인 (2)
    • Algorithm (204)
      • BOJ (160)
      • 프로그래머스 (19)
      • LeetCode (4)
      • SWEA (1)
      • 알고리즘 문제 해결 전략 (8)
      • DS, algorithms (7)
      • Checkio (5)
    • IT (2)

블로그 메뉴

  • GitHub
  • 글쓰기
  • 관리자

공지사항

  • Free!

인기 글

태그

  • DFS
  • django
  • 다이나믹 프로그래밍
  • docker
  • 프로그래머스
  • 백트래킹
  • Network
  • boj
  • BFS
  • Kubernetes

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Henu

개발냥발

[백준 1238] 파티 C++
Algorithm/BOJ

[백준 1238] 파티 C++

2021. 7. 5. 16:55
 

1238번: 파티

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

www.acmicpc.net

다익스트라


1. 문제 해결 아이디어

 

단순한 다익스트라 문제는 A->B까지 가는 거리의 최단거리를 구하는 것이지만

이 문제는 A->X로가는 최단거리 + X->A로 되돌아오는 최단거리를 구해야 한다.

 

A->X로 가는 최단거리를 구해보자.

 

정점의 개수가 최대 1000개, 간선의 개수가 최대 10000개 이므로 O(|V||E|) = 10,000,000 이 되어 시간내에 풀 수 있다고 생각했다.

그래서 A->X로 가는 최단거리를 A의 개수만큼 반복문을 돌려서 다익스트라 알고리즘을 수행한 후 배열에 각각 저장했다.

resdist[A] = X로 가는 최단거리

 

이제 모든 정점에서 X로 가는 최단거리를 구했다.

 

X에서 다른 정점으로 가는 최단거리들을 구하는건 일반적인 다익스트라 알고리즘을 한 번만 수행하면 된다.

 


그런데 정점의 개수가 100,000개가 되면 위 풀이를 쓸 수가 없다

 

정점들의 정보를 입력 받을 때 역방향 간선을 따로 입력 받아 보자

 

역방향으로 입력을 받으면 각 정점들(A)에서 X로 가는 최단거리를 X->A 최단거리로 바꿀 수 있다!

다익스트라 한 번이면 각 정점들에서 X로 가는 최단거리배열을 구할 수 있다는 것이다.

 

 

시간차이가 어마어마하게 많이 나는걸 볼 수 있다


2. 코드 - 최적화 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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <vector>
#include <queue>
 
#define pii pair<int, int>
 
using namespace std;
 
 
int N, M, X;
const int INF = 1e9+7;
vector<pii > graph[1001]; 
vector<int> dist;
int resdist[1001];
 
void input(){
    int u, v, t;
    cin >> N >> M >> X;
    for(int i = 0; i < M; i++){
        cin >> u >> v >> t;
        graph[u].push_back(make_pair(t, v));
    }
}
 
void Dijstra(int S){
    dist.clear();
    dist.resize(N+1, INF);
    
    dist[S] = 0;
    
    priority_queue<pii, vector<pii >, greater<pii > > que;
    que.push({0, S});
    
    while(!que.empty()){
        int min_cost = que.top().first;
        int now = que.top().second;
        que.pop();
        
        if(min_cost > dist[now]) continue;
        
        for(int i = 0; i < graph[now].size(); i++){
            int next = graph[now][i].second;
            int next_cost = min_cost + graph[now][i].first;
            
            if(next_cost < dist[next]){
                dist[next] = next_cost;
                que.push({next_cost, next});
            }
        }
    }
}
 
int main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    input();
    for(int i = 1; i <= N; i++){
        Dijstra(i);
        // i가 X로 가는 최단거리 half
        resdist[i] = dist[X];
    }
    Dijstra(X);
    int res = 0;
    for(int i = 1; i <= N; i++){
        resdist[i] += dist[i];
        res = max(res, resdist[i]);
    }
    
    cout << res;
    
    return 0;
}
Colored by Color Scripter
cs

 


2. 코드 - 최적화 O

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <vector>
#include <queue>
 
#define pii pair<int, int>
 
using namespace std;
 
 
int N, M, X;
const int INF = 1e9+7;
vector<pii > graph[2][1001]; 
vector<int> dist[2];
int resdist[1001];
 
void input(){
    int u, v, t;
    cin >> N >> M >> X;
    for(int i = 0; i < M; i++){
        cin >> u >> v >> t;
        graph[0][u].push_back(make_pair(t, v));
        graph[1][v].push_back(make_pair(t, u));
    }
    dist[0].resize(N+1, INF);
    dist[1].resize(N+1, INF);
}
 
void Dijstra(int k){
    dist[k][X] = 0;
    
    priority_queue<pii, vector<pii >, greater<pii > > que;
    que.push({0, X});
    
    while(!que.empty()){
        int min_cost = que.top().first;
        int now = que.top().second;
        que.pop();
        
        if(min_cost > dist[k][now]) continue;
        
        for(int i = 0; i < graph[k][now].size(); i++){
            int next = graph[k][now][i].second;
            int next_cost = min_cost + graph[k][now][i].first;
            
            if(next_cost < dist[k][next]){
                dist[k][next] = next_cost;
                que.push({next_cost, next});
            }
        }
    }
}
 
int main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    input();
    
    // 정점들에서 X로 가는 최단거리
    Dijstra(1);
    
    // X에서 정점들로 가는 최단거리
    Dijstra(0);
    
    int res = 0;
    for(int i = 1; i <= N; i++){
        res = max(res, dist[0][i] + dist[1][i]);
    }
    
    cout << res;
    
    return 0;
}
Colored by Color Scripter
cs

 

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

[백준 6087] 레이저 통신 C++  (0) 2021.07.06
[백준 14890] 경사로 C++  (0) 2021.07.06
[백준 1509] 팰린드롬 분할 C++  (0) 2021.07.02
[백준 3197] 백조의 호수  (0) 2021.07.01
[백준 2636] 치즈 C++  (0) 2021.07.01
    'Algorithm/BOJ' 카테고리의 다른 글
    • [백준 6087] 레이저 통신 C++
    • [백준 14890] 경사로 C++
    • [백준 1509] 팰린드롬 분할 C++
    • [백준 3197] 백조의 호수

    티스토리툴바