백준 온라인 저지 1238번 파티
문제 출처 : https://www.acmicpc.net/problem/1238
1238번: 파티
문제 N개의 숫자로 구분된 각각의 마을에 한 명의 학생이 살고 있다. 어느 날 이 N명의 학생이 X (1 ≤ X ≤ N)번 마을에 모여서 파티를 벌이기로 했다. 이 마을 사이에는 총 M개의 단방향 도로들이 있고 i번째 길을 지나는데 Ti(1 ≤ Ti ≤ 100)의 시간을 소비한다. 각각의 학생들은 파티에 참석하기 위해 걸어가서 다시 그들의 마을로 돌아와야 한다. 하지만 이 학생들은 워낙 게을러서 최단 시간에 오고 가기를 원한다. 이 도로들은 단방향이기 때
www.acmicpc.net
풀이 과정
처음 문제를 읽고 최단경로를 구하는 알고리즘이라고 판단했고 가장 쉽게 구현할 수 있는 플로이드-워셜 알고리즘을 생각했습니다. 그러나 정점의 최대 입력이 1000이라는 것을 생각했을 때 O(N^3) 일 경우 시간 초과가 나기 때문에 다익스트라 알고리즘을 사용해야 합니다.
입력받은 정점에 대해서 각각 다익스트라 알고리즘을 수행해야 할지 고민하던 중 입력받은 그래프를 역으로 바꾼 그래프를 만들어 총 2번의 다익스트라 알고리즘을 수행하여 답을 구할 수 있도록 했습니다.
1. 처음 입력받은 그래프를 통해 파티 장소에서 마을까지의 최단경로를 계산
2. 역으로 바꾼 그래프를 통해 각각의 마을에서 파티 장소까지의 최단경로를 계산
소스 코드
#include <iostream> #include <vector> #include <queue> #include <cmath> #define MAX 987654321 using namespace std; using pp = pair<int, int>; int n, m, x; vector<pp> map[1001], reverse_map[1001]; int dist[1001], sum[1001]; void dijkstra(vector<pp> map[1001], int start) { for(int i=0; i<n;i++) { dist[i] = MAX; } dist[start] = 0 ; priority_queue<pp> pq; pq.push(make_pair(0,start)); while(!pq.empty()) { int distance = pq.top().first; int vertex = pq.top().second; pq.pop(); if(dist[vertex] < distance) continue; for(int i=0; i<map[vertex].size();i++) { int v = map[vertex][i].first; int d = map[vertex][i].second + distance; if( d< dist[v] ) { pq.push(make_pair(d,v)); dist [v] = d; } } } for(int i=0; i<n;i++) { sum[i] += dist[i]; } } int main() { ios_base::sync_with_stdio(false); 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; map[a - 1].push_back(make_pair(b - 1, c)); reverse_map[b - 1].push_back(make_pair(a - 1, c)); } dijkstra(map,x-1); dijkstra(reverse_map,x-1); int _max =0; for(int i=0; i<n;i++) { if( i == x-1 ) continue; _max = max(_max,sum[i]); } cout << _max << endl; }
'백준온라인저지' 카테고리의 다른 글
11286번 절댓값 힙 (0) | 2019.10.22 |
---|---|
2804번 크로스워드 만들기 (0) | 2019.10.03 |
3062번 수 뒤집기 (0) | 2019.07.18 |
2417번 정수 제곱근 (0) | 2019.07.12 |
1991번 트리순회 (0) | 2019.01.20 |