※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 1746번 문제인 단체 릴레이이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/1746
1746번: 단체 릴레이
첫째 줄에 학생의 수 N(2 ≤ N ≤ 1,000,000)과 구역의 수(2 ≤ T ≤ 100) 시작지점의 번호 S(1 ≤ S ≤ 1000) 도착지점의 번호 E(1 ≤ E ≤ 1000)가 주어진다. 그 다음 T개의 줄에 간선의 길이 L (1 ≤ L ≤ 1,000)
www.acmicpc.net
각 지점에서 다른 지점까지 1번, 2번, ..., 2^K번 움직여 이동하는 최단거리들은 각각 O(V^3) (V는 그래프의 노드 개수)에 구할 수 있다. (Floyd-Warshall과 비슷하게 구현하면 된다.)
이제 N의 이진수 표현과 위에서 구한 최단거리들을 이용하여 각 지점에서 다른 지점까지 N개의 에지를 거쳐 이동하는 최단거리를 구할 수 있다. 이것 또한 Floyd-Warshall의 dp 점화식과 같이 처리하면 계산해낼 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <utility>
#include <cstring>
using namespace std;
int idx = 1;
int nodetoidx[1001];
int dist[20][201][201];
int ans[201][201];
int nxt[201][201];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int K, M, S, E; cin >> K >> M >> S >> E;
while (M--) {
int x, y, d; cin >> d >> x >> y;
if (nodetoidx[x] == 0) nodetoidx[x] = idx++;
if (nodetoidx[y] == 0) nodetoidx[y] = idx++;
x = nodetoidx[x], y = nodetoidx[y];
dist[0][x][y] = dist[0][y][x] = d;
}
for (int r = 1; r < idx; r++) {
for (int c = 1; c < idx; c++) {
if (dist[0][r][c] == 0) dist[0][r][c] = 1000000007;
}
}
for (int p = 1; p < 20; p++) {
for (int r = 1; r < idx; r++) {
for (int c = r; c < idx; c++) {
int& d = dist[p][r][c] = 1000000007;
for (int k = 1; k < idx; k++) {
d = min(d, dist[p - 1][r][k] + dist[p - 1][k][c]);
}
dist[p][c][r] = d;
}
}
}
for (int r = 1; r < idx; r++) {
for (int c = 1; c < idx; c++) ans[r][c] = 1000000007;
ans[r][r] = 0;
}
int p = 0;
while (K) {
if (K & 1) {
for (int r = 1; r < idx; r++) {
for (int c = r; c < idx; c++) {
int& d = nxt[r][c] = 1000000007;
for (int k = 1; k < idx; k++) {
d = min(d, ans[r][k] + dist[p][k][c]);
}
nxt[c][r] = d;
}
}
swap(ans, nxt);
}
p++;
K >>= 1;
}
S = nodetoidx[S], E = nodetoidx[E];
cout << ans[S][E];
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 12720 // C++] Number Sets (Large) (0) | 2022.05.22 |
---|---|
[BOJ 2458 // C++] 키 순서 (0) | 2022.05.22 |
[BOJ 23258 // C++] 밤편지 (0) | 2022.05.21 |
[BOJ 1719 // C++] 택배 (0) | 2022.05.20 |
[BOJ 12022 // C++] 짝 (0) | 2022.05.19 |