문제 이름 : 파티 (1238번)
문제 유형 : 그래프 이론, 다익스트라
작성 언어 : C++
문제
N개의 숫자로 구분된 각각의 마을에 한 명의 학생이 살고 있다.
어느 날 이 N명의 학생이 X (1 ≤ X ≤ N)번 마을에 모여서 파티를 벌이기로 했다. 이 마을 사이에는 총 M개의 단방향 도로들이 있고 i번째 길을 지나는데 Ti(1 ≤ Ti ≤ 100)의 시간을 소비한다.
각각의 학생들은 파티에 참석하기 위해 걸어가서 다시 그들의 마을로 돌아와야 한다. 하지만 이 학생들은 워낙 게을러서 최단 시간에 오고 가기를 원한다.
이 도로들은 단방향이기 때문에 아마 그들이 오고 가는 길이 다를지도 모른다. N명의 학생들 중 오고 가는데 가장 많은 시간을 소비하는 학생은 누구일지 구하여라.
입력
첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 10,000), X가 공백으로 구분되어 입력된다. 두 번째 줄부터 M+1번째 줄까지 i번째 도로의 시작점, 끝점, 그리고 이 도로를 지나는데 필요한 소요시간 Ti가 들어온다. 시작점과 끝점이 같은 도로는 없으며, 시작점과 한 도시 A에서 다른 도시 B로 가는 도로의 개수는 최대 1개이다.
모든 학생들은 집에서 X에 갈수 있고, X에서 집으로 돌아올 수 있는 데이터만 입력으로 주어진다.
출력
첫 번째 줄에 N명의 학생들 중 오고 가는데 가장 오래 걸리는 학생의 소요시간을 출력한다.
예제 입력 1
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
예제 출력 1
10
풀이
문제 이해)
예제 입출력 1을 직접 그려보았다.
4명의 학생이 8개의 도로가있을때 2번마을에서 파티를한다.
1 에서 2를 가는 최단경로는 4 (1->2)
2 에서 1로 돌아오는 최단경로는 1 (2->1)
따라서 1은 2번까지 오고 가는데 5만큼의 시간이걸린다.
3 에서 2를 가는 최단경로는 (3->1->2) 6이다
2 에서 3로 돌아오는 최단경로는 (2->1->3) 3이다
따라서 3은 2번까지 오고 가는데 9만큼의 시간이걸린다.
4 에서 2를 가는 최단경로는 (4->2) 3이다
2 에서 4로 돌아오는 최단경로는 (2->1->3->4) 7이다
따라서 4는 2번까지 오고 가는데 10만큼의 시간이걸린다.
출력 : 위의 세가지경우중 가장오래걸리는 4번시간을 출력 (10)
최단거리 계산을 위하여 다익스트라 알고리즘과 우선순위 큐를 이용하였다.
작성 코드
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define INF 987654321
int N,M,X;
int dist[1001]={0};
vector < pair<int, int> > w[1001];
int ans=0;
//s노드부터 X노드까지의 최단경로 찾기(다익스트라알고리즘)
void FindSpath(int s)
{
priority_queue< pair<int, int> > pq;
pq.push({ 0, s });
while(!pq.empty())
{
int now_cost = -pq.top().first;
int now_city = pq.top().second;
pq.pop();
//구식정보 이정보로 인접 노드로의 거리를 계산해도 쓸모가없음
if(dist[now_city] < now_cost)
{
continue;
}
for(vector<int>::size_type i = 0; i < w[now_city].size();i++)
{
int next_city = w[now_city][i].first;
int next_cost = w[now_city][i].second;
if(dist[next_city] > now_cost + next_cost)
{
dist[next_city] = now_cost + next_cost;
pq.push({ -dist[next_city], next_city});
}
}
}
ans += dist[X];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
//초기화단계
int max = 0;
int tmp_X;
//입력단계
int input_st, input_ed, input_w;
cin >> N >> M >> X;
for(int i=0; i<M; i++)
{
cin >> input_st >> input_ed >> input_w;
w[input_st].push_back(make_pair(input_ed, input_w));
}
// X노드 번호백업
tmp_X = X;
//1번부터 N번노드까지 최단경로 왕복 값 계산
for(int i=1;i<=N;i++)
{
X=tmp_X;
ans=0;
//X->X 경우, 최단거리 0!!
if(i==tmp_X)
{
continue;
}
for(int j=1;j<=N;j++)
{
dist[j] = INF;
}
FindSpath(i); // i번 노드에서 x번노드 편도최단거리 계산
for(int j=1;j<=N;j++)
{
dist[j] = INF;
}
X = i;
FindSpath(tmp_X); //X번 노드에서 i번 노드로의 편도 최단거리 계산
//cout << i << ": " <<ans << '\n';
//정답갱신
max = ans > max ? ans : max; //큰거를 max에 갱신
}
cout << max << '\n';
return 0;
}
https://www.acmicpc.net/problem/1238
'알고리즘' 카테고리의 다른 글
BOJ_1806_부분합 (0) | 2021.07.27 |
---|---|
BOJ_1916_최소비용 구하기 (0) | 2021.07.26 |
BOJ_1260_DFS와 BFS (0) | 2021.07.24 |
BOJ_14627_파닭파닭 (0) | 2021.07.23 |
BOJ_13335_트럭 (0) | 2021.07.22 |
댓글