※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 5590번 문제인 船旅이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/5590
5590번: 船旅
入力の 1 行目には2つの整数 n, k (1 ≦ n ≦ 100, 1 ≦ k ≦ 5000) が書かれている. これは,島の数が n 島で,入力が k + 1 行からなることを表す. i + 1 行目 (1 ≦ i ≦ k) には, 3 個または 4 個の
www.acmicpc.net
100 이하의 정수 N개의 섬과 이들 사이의 선박편의 비용이 주어지는 그래프가 주어진다.
0번 쿼리가 주어지면 주어지는 두 섬 사이의 최단거리를 출력하고, 1번 쿼리가 주어지면 새로운 배편을 그래프에 추가하자.
섬의 개수 N과 쿼리의 수 K가 적으므로, 어떤 그래프 최단거리 알고리즘을 사용해도 문제를 해결할 수 있다.
그 중 두 섬 사이의 최단거리가 갱신되었을 때 O(N)의 추가연산만으로 모든 섬 사이의 최단거리를 갱신할 수 있는 Floyd-Warshall 알고리즘이 가장 효율이 좋을 것으로 예상된다.
글쓴이는 최단거리를 구할 때마다 Dijkstra 알고리즘을 돌려 문제를 해결하였다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
int N, Q;
vector<pair<int, int>> G[101]; // (좌표, 거리)
int dist[101];
int dijkstra(int s, int e) {
memset(dist, 0, sizeof(dist));
dist[s] = 1;
priority_queue<pair<int, int>> pq; // (-거리, 좌표)
pq.push(make_pair(-1, s));
while (!pq.empty()) {
int cur = pq.top().second, d = -pq.top().first;
pq.pop();
if (dist[cur] < d) continue;
for (auto p : G[cur]) {
int node = p.first, dd = p.second;
if (dist[node] == 0 || d + dd < dist[node]) {
dist[node] = d + dd;
pq.push(make_pair(-(d + dd), node));
}
}
}
return dist[e] - 1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> Q;
while (Q--) {
int q; cin >> q;
if (q == 0) {
int x, y; cin >> x >> y;
cout << dijkstra(x, y) << '\n';
}
else {
int x, y, d; cin >> x >> y >> d;
G[x].emplace_back(make_pair(y,d));
G[y].emplace_back(make_pair(x,d));
}
}
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 5587 // C++] 카드 캡터 상근이 (0) | 2022.06.19 |
---|---|
[BOJ 14730 // C++] 謎紛芥索紀 (Small) (0) | 2022.06.19 |
[BOJ 14732 // C++] 행사장 대여 (Small) (0) | 2022.06.19 |
[BOJ 5589 // C++] おせんべい (0) | 2022.06.19 |
[BOJ 24073 // C++] ビ太郎と IOI (Bitaro and IOI) (0) | 2022.06.18 |