※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 13141번 문제인 Ignition이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/13141
13141번: Ignition
첫 번째 줄에는 그래프의 정점의 수 N과 간선의 수 M이 주어진다. (2 ≤ N ≤ 200, N-1 ≤ M ≤ 20,000) 두 번째 줄부터 M개의 줄에는 각 간선의 시작점 S, 끝점 E, 길이 L이 주어진다. (1 ≤ L ≤ 100) 시작점
www.acmicpc.net
한 노드에 불을 붙였을 때 모든 그래프가 다 타는 시점은 모든 에지가 다 타는 시점과 동일하다.
각 에지가 전부 타는 시점은 한쪽 노드가 타기 시작하는 시점과 양쪽 노드 모두 타기 시작하는 시점, 그리고 에지의 길이를 이용해 하나씩 모두 구해볼 수 있다.
Floyd-Warshall 알고리즘을 이용해 각 노드에 불을 붙였을 때 다른 노드가 타기 시작하는 시점을 미리 전처리하고, 각 노드에 불을 붙였을 때의 모든 에지가 타는 시점을 전부 계산해 문제를 해결하자.
각 노드가 타오르기 시작하는 시점을 계산할 때는 두 노드를 연결하는 최단거리의 에지만을 확인하면 되지만 그래프가 완전히 타오르는 시점을 찾을 때는 두 노드를 연결하는 더 긴 길이의 에지 또한 고려해야 함에 유의하자.
아래는 제출한 소스코드이다.
#include <iostream>
using namespace std;
int dist[201][201];
int edgeL[20000], edgeR[20000], distedge[20000];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int N, M; cin >> N >> M;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) dist[i][j] = 1000000007;
}
for (int m = 0; m < M; m++) {
int S, E, L; cin >> S >> E >> L;
dist[S][E] = dist[E][S] = min(dist[S][E], L);
edgeL[m] = S, edgeR[m] = E, distedge[m] = L;
}
for (int i = 1; i <= N; i++) dist[i][i] = 0;
for (int k = 1; k <= N; k++) {
for (int r = 1; r <= N; r++) {
for (int c = 1; c <= N; c++) {
dist[r][c] = min(dist[r][c], dist[r][k] + dist[k][c]);
}
}
}
int ans = 1000000007;
for (int k = 1; k <= N; k++) {
int tmp = 0;
for (int m = 0; m < M; m++) {
int d1 = dist[k][edgeL[m]], d2 = dist[k][edgeR[m]], l = distedge[m];
int diff = abs(d1 - d2);
l -= diff;
tmp = max(tmp, 2 * max(d1, d2) + l);
}
ans = min(ans, tmp);
}
cout << ans / 2 << '.';
if (ans & 1) cout << 5;
else cout << 0;
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 6135 // C++] Cow Hurdles (0) | 2022.05.22 |
---|---|
[BOJ 12719 // C++] Number Sets (Small) (0) | 2022.05.22 |
[BOJ 12721 // C++] Mousetrap (Small) (0) | 2022.05.22 |
[BOJ 24617 // C++] Redistributing Gifts (0) | 2022.05.22 |
[BOJ 12717 // C++] Crop Triangles (Small) (0) | 2022.05.22 |