[백준] 운동 (1956)(kotlin)
문제 설명
입력 및 출력
» 입력
첫째 줄에 V와 E가 빈칸을 사이에 두고 주어진다. (2 ≤ V ≤ 400, 0 ≤ E ≤ V(V-1)) 다음 E개의 줄에는 각각 세 개의 정수 a, b, c가 주어진다. a번 마을에서 b번 마을로 가는 거리가 c인 도로가 있다는 의미이다. (a → b임에 주의) 거리는 10,000 이하의 자연수이다. (a, b) 쌍이 같은 도로가 여러 번 주어지지 않는다.
» 출력
첫째 줄에 최소 사이클의 도로 길이의 합을 출력한다. 운동 경로를 찾는 것이 불가능한 경우에는 -1을 출력한다.
예제 입출력(테스트케이스)
입력 | 출력 |
---|---|
3 4 1 2 1 3 2 1 1 3 5 2 3 2 |
3 |
문제 풀이1
fun main() = with(System.`in`.bufferedReader()) {
val (V, E) = readLine().split(" ").map { it.toInt() }
// c의 최댓값은 400 * 10_000
val matrix = Array(V + 1) { IntArray(V + 1) { 40_000_001 } }
repeat(E) {
val (a, b, c) = readLine().split(" ").map { it.toInt() }
// (단방향) a에서 b로 가는 비용이 c
matrix[a][b] = c
}
for (i in 1..V) for (j in 1..V) for (k in 1..V) {
// i -> j로 갈 때, i -> k -> j로 k를 경유해서 가는 비용과 비교하여
if (matrix[i][j] > matrix[i][k] + matrix[k][j]) {
// k로 경유해서 가는 비용이 i -> j로 가는 최소비용보다 작으면 그 최소비용을 갱신
matrix[i][j] = matrix[i][k] + matrix[k][j]
}
}
// 비용인 c가 가질 수 있는 최댓값으로 최솟값을 초기화
var min = 40_000_001
for (i in 1..V) for (j in 1..V) {
// i -> j -> i, i에서 시작해서 j를 경유해 i로 복귀하는 값들 중 최솟 비용을 탐색
min = Math.min(min, matrix[i][j] + matrix[j][i])
}
// 최소비용이 갱신되지 않았으면, 해당하는 경로가 없으므로 -1
// 그렇지 않으면 최솟값을 출력
if (min == 40_000_001) println(-1)
else println(min)
}