백준온라인저지

1238번 파티

wonjjong 2019. 7. 18. 21:50

백준 온라인 저지 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