체뚱로그
[백준/C++] 11265 - 끝나지 않는 파티 본문
풀이 시간: 30:46
시간 복잡도: O(N+M+N^3) = O(N^3) // floyd_warshall()의 O(N^3)
공간 복잡도: O(N^2) // party_hall의 공간 복잡도
참고 자료: https://chanhuiseok.github.io/posts/algo-50/
문제
파티를 좋아하는 민호는 끝없이 파티가 열리는 놀이동산 "민호월드"를 세웠다. 처음에는 한개의 파티장만을 가지고 있는 작은 놀이동산이었지만, 사람들의 점점 많이 찾아와 파티장을 증축했고 현재는 N개의 파티장을 가진 큰 놀이동산이 되었다. 민호는 파티장을 증축할때마다 편의를 위해 새로운 파티장과 기존의 모든 파티장이 직접적으로 연결이 될 수 있는 도로들을 만들었다. 이때 만들어진 도로들은 사용자들의 편의를 위해 일방통행으로 설계가 되었다.
파티장이 적을때는 괜찮았지만 파티장이 많아진 지금 다음과 같은 두 가지 문제점이 발생했다.
- A 파티장에서 B 파티장으로 빨리 갈 수 있도록 직접 연결이 된 일방통행 도로를 만들었지만 A와 B가 아닌 다른 파티장을 경유해서 더 빨리 갈 수 있는 경우가 있을 수 있다.
- 지금으로부터 C만큼의 시간 뒤에 B번 파티장에서 새롭게 파티가 열리는데 1번과 같은 이유때문에 현재 있는 A파티장에서 B번 파티장까지 파티가 열리는 시간까지 맞춰 갈 수 있는지 쉽게 알 수 없다.
이러한 문제점으로 이용객들의 불만이 점점 커져갔고 민호는 이를 해결하기 위해 빠른 네비게이션 서비스를 실행하기로 하였으나 서비스 요청이 너무 많아 업무가 마비되기에 이르렀다. 이에 민호는 천재프로그래머인 당신에게 이 문제를 해결해 달라고 요청하였다. 민호를 도와 한 파티장에서 다른 파티장에까지 시간내에 도착할 수 있는지 없는지 알아봐주는 프로그램을 작성하자.
입력
입력의 첫 번째 줄에는 파티장의 크기 N(5 ≤ N ≤ 500)과 서비스를 요청한 손님의 수 M(1 ≤ M ≤ 10,000) 이 주어진다. 각각의 파티장은 1번부터 N번까지 번호가 붙여져 있다. 다음에는 N개의 줄에 걸쳐 각각 N개의 수가 주어진다. i번째 줄의 j번째 수 T(1 ≤ T ≤ 1,000,000)는 i번 파티장에서 j번 파티장으로 직접적으로 연결된 도로를 통해 이동하는 시간을 의미한다.
다음 M개의 줄에는 세개의 정수 A, B, C가 주어진다. A(1 ≤ A ≤ N) 는 서비스를 요청한 손님이 위치한 파티장의 번호, B(1 ≤ B ≤ N) 다음 파티가 열리는 파티장의 번호, C(1 ≤ C ≤ 1,000,000,000)는 지금으로부터 다음 파티가 열리는데 걸리는 시간을 의미한다.
출력
M개의 줄에 걸쳐 서비스를 요청한 손님이 시간내에 다른 파티장에 도착할 수 있으면 “Enjoy other party”를, 시간내에 도착할 수 없으면 "Stay here”를 출력한다.
문제풀이
본 문제는 플로이드-워셜(Floyd-Warshall) 알고리즘을 사용하여 매우 간단하게 풀 수 있다.
전체 코드
#include <iostream>
#include <vector>
using namespace std;
int N, M;
vector<vector<int>> party_hall;
// 중간 노드 k를 거쳐서 가는 이동 시간과 현재 이동 시간 비교하여 더 작은 값으로 갱신
void floyd_warshall() {
for (int k = 0; k < N; k++)
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
party_hall[i][j] = min(party_hall[i][j], party_hall[i][k] + party_hall[k][j]);
}
int main(void) {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N >> M;
party_hall = vector<vector<int>>(N); // 파티장 2차원 벡터
for (int i = 0; i < N; i++) { // 파티장 이동 시간 초기화
party_hall[i] = vector<int>(N);
for (int j = 0; j < N; j++) {
cin >> party_hall[i][j];
}
}
floyd_warshall(); // 플로이드-워셜 알고리즘
// A에서 B로 이동하는 시간이 시간 C를 넘지 않는지 확인
for (int i = 0; i < M; i++) {
int A, B, C;
cin >> A >> B >> C;
if (party_hall[A - 1][B - 1] <= C) cout << "Enjoy other party" << endl;
else cout << "Stay here" << endl;
}
}
https://www.acmicpc.net/problem/11265
'PS > BOJ' 카테고리의 다른 글
[백준/C++] 1277 - 발전소 설치 (0) | 2023.12.28 |
---|---|
[백준/C++] 14938 - 서강그라운드 (0) | 2023.12.19 |
[백준/C++] 18352 - 특정 거리의 도시 찾기 (0) | 2023.12.19 |
[백준/C++] 1600 - 말이 되고픈 원숭이 (0) | 2023.11.27 |
[백준/C++] 5547 - 일루미네이션 (0) | 2023.11.27 |