https://www.acmicpc.net/problem/11265
11265번: 끝나지 않는 파티
입력의 첫 번째 줄에는 파티장의 크기 N(5 ≤ N ≤ 500)과 서비스를 요청한 손님의 수 M(1 ≤ M ≤ 10,000) 이 주어진다. 각각의 파티장은 1번부터 N번까지 번호가 붙여져 있다. 다음에는 N개의 줄에 걸
www.acmicpc.net
알고리즘 방식
- 플로이드 워셜 방식으로 구현이 가능한 알고리즘이며
다익스트라를 활용해도 구현이 가능한 알고리즘이였다.
먼저 정점의 개수는 V, 간선의 개수는 E이며, V^2 >= E가 성립한다.
다익스트라의 경우 시간복잡도는 O(ElogV)이다.
플로이드 워셜의 경우 시간복잡도는 O(E^3)이다.
다익스트라를 활용한 풀이의 경우 기본 다익스트라 알고리즘에 for문을 씌웠기 때문에 O(VElogV)로 시간복잡도가 O(V^3)인 플로이드 워셜보다 빠를거라 생각했다. 하지만, 플로이드 워셜이 훨씬 빨랐다.
이에대해 고찰해봤는데, 핵심은 간선의 개수에 있었다. 플로이드 워셜은 간선의 개수와 상관없이 시간복잡도가 일정하지만, 다익스트라의 경우 시간복잡도가 간선의 개수에 영향을 많이 받을 수 밖에 없기 때문에, 간선의 개수가 적을 경우 전자가 더 빠르겠지만, 간선의 개수가 많아질 경우 플로이드 워셜이 더 빠르다.
소스코드
for문을 씌운 다익스트라
#include <iostream> #include <vector> #include <queue> #define INF 987654321 using namespace std; int N, M; vector<vector<int>> node; vector<vector<int>> val; vector<string> answer; priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq; //n*nlogn void daijkstra() { for (int from = 0; from < N; from++) { pq.push({ 0, from }); val[from][from] = 0; while (!pq.empty()) { int disSum = pq.top().first; int loc = pq.top().second; pq.pop(); for (int to = 0; to < N; to++) { int x = node[loc][to]; if (disSum + x < val[from][to]) { val[from][to] = disSum + x; pq.push({ val[from][to], to }); } } } } } int main(void) { ios::sync_with_stdio(false); cin.tie(NULL); cin >> N >> M; node.assign(N, vector<int>(N, 0)); val.assign(N, vector<int>(N, INF)); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { cin >> node[i][j]; } } daijkstra(); int A, B, C; for (int i = 0; i < M; i++) { cin >> A >> B >> C; if (val[A - 1][B - 1] <= C) answer.push_back("Enjoy other party\n"); else answer.push_back("Stay here\n"); } for (auto v : answer) cout << v; }

플로이드-워셜
#include <iostream> #include <vector> #include <queue> #define INF 987654321 using namespace std; int N, M; vector<vector<int>> floyd; vector<string> answer; //n^3 void FloydWarshall() { for (int by = 0; by < N; by++) { for (int from = 0; from < N; from++) { for (int to = 0; to < N; to++) { if (floyd[from][by] + floyd[by][to] < floyd[from][to]) floyd[from][to] = floyd[from][by] + floyd[by][to]; } } } }//from by to int main(void) { ios::sync_with_stdio(false); cin.tie(NULL); cin >> N >> M; floyd.assign(N, vector<int>(N, 0)); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { cin >> floyd[i][j]; } } FloydWarshall(); int A, B, C; for (int i = 0; i < M; i++) { cin >> A >> B >> C; if (floyd[A - 1][B - 1] <= C) answer.push_back("Enjoy other party\n"); else answer.push_back("Stay here\n"); } for (auto v : answer) cout << v; }

'알고리즘 > C++' 카테고리의 다른 글
[백준] 1261 - 알고스팟 by C++ (0) | 2023.03.24 |
---|---|
[백준] 23564 - 재귀 문자열 by C++ (0) | 2023.01.27 |
[백준] 1520 - 내리막 길 (0) | 2023.01.09 |
[백준] 18870 - 좌표 압축 (0) | 2022.12.30 |
[백준] 3079 - 입국심사 by C++ (0) | 2022.12.22 |
댓글