※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 23258번 문제인 밤편지이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/23258
23258번: 밤편지
$C = 3$일 때, 1번 정점에서 4번 정점으로 가는 경로 중 3번 정점을 지나는 경로는 반딧불이 3번 정점에서 8방울의 이슬을 마시고 잠들어버리기 때문에 불가능하다. 따라서 가능한 경로는 2번 정점
www.acmicpc.net
먼저 각 반딧불은 상수 C에 따라 집의 번호가 C 미만인 집들만을 방문할 수 있게 된다. 이들 집의 모든 이슬을 마시더라도 2^C보다 적은 이슬을 마시게 되므로 방문할 수 있는 집의 개수 제한은 없다.
주어진 쿼리들을 C가 작은 쿼리부터 하나씩 보면서 Floyd-Warshall 알고리즘을 (이전 상태에서부터 이어서) C 미만의 노드까지만 진행시켜 집의 번호가 C 이상인 집들을 중간에 거치는 경우가 없는 최단거리를 구하고, 쿼리의 입력순으로 답을 출력해 문제를 해결하자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
struct query {
int s, e, C, idx;
query() {};
query(int s, int e, int C, int idx) {
this->s = s, this->e = e, this->C = C, this->idx = idx;
}
};
bool comp(query q1, query q2) {
return q1.C < q2.C;
}
ll dist[301][301];
int ans[500000];
query queries[500000];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N, Q; cin >> N >> Q;
for (int r = 1; r <= N; r++) {
for (int c = 1; c <= N; c++) {
cin >> dist[r][c];
if (r != c && dist[r][c] == 0) dist[r][c] = 1000000007;
}
}
for (int q = 0; q < Q; q++) {
int C, s, e; cin >> C >> s >> e;
queries[q] = query(s, e, C, q);
}
sort(queries, queries + Q, comp);
int k = 1;
for (int q = 0; q < Q; q++) {
auto& qry = queries[q];
int C = qry.C;
while (k < C) {
for (int r = 1; r <= N; r++) {
for (int c = r + 1; c <= N; c++) {
if (dist[r][k] + dist[k][c] < dist[r][c]) dist[r][c] = dist[c][r] = dist[r][k] + dist[k][c];
}
}
k++;
}
if (dist[qry.s][qry.e] > 1000000000) ans[qry.idx] = -1;
else ans[qry.idx] = dist[qry.s][qry.e];
}
for (int i = 0; i < Q; i++) cout << ans[i] << '\n';
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 2458 // C++] 키 순서 (0) | 2022.05.22 |
---|---|
[BOJ 1746 // C++] 단체 릴레이 (0) | 2022.05.22 |
[BOJ 1719 // C++] 택배 (0) | 2022.05.20 |
[BOJ 12022 // C++] 짝 (0) | 2022.05.19 |
[BOJ 2174 // C++] 로봇 시뮬레이션 (0) | 2022.05.18 |