BOJ 1197 네트워크 연결
접근 방식
최소 스패닝 트리 기본형. 크루스칼로 풀되 사이클 판정은 find-union으로 처리함. 간선을 비용 오름차순으로 정렬하고, 두 끝점의 루트가 다를 때만 비용을 더함.
알고리즘 자체는 익숙한데 구현에서 자잘한 실수가 반복돼서 그 부분을 정리함.
시행착오

최소 스패닝 트리에서의 내 실수들
- union 함수에서 num1, num2도 find 함수를 통해 구해야 함. (자꾸 parent[i]로 세팅하는 실수를 범함)
- parent의 개수를 지정할 때는 노드의 개수(정점의 수)만큼 지정해야 함. (실수로 간선의 개수로 설정하기도 함)
- 간선의 리스트를 세팅할 때는 정점의 개수가 아닌 간선의 개수로 해야 함. (이 문제에서는 이것 때문에 한참 헤맸음)
- 비용을 기준으로 오름차순으로 정렬함. (정렬도 깜빡한 적 있음)
- 두 부분으로 나눌 때는 last 값을 기록해서 빼줌.
- 그래프를 입력받으면서 세팅해야 시간 면에서 유리함. (백준에서 스위프트 언어 사용하면 시간 초과가 남)
- 튜플을 주로 쓰는데, 그냥 배열을 쓰는 게 여기서는 나음. (이것도 백준에서 시간 초과 문제)
- find 함수에서 parent[i] = find(i)로 넣는 실수를 하는데 find(parent[i])로 넣어야 함.
코드
// https://www.acmicpc.net/problem/1922
import Foundation
struct b1922 {
static func run() {
let v = Int(readLine()!)!
let e = Int(readLine()!)!
var graph: [[Int]] = []
var parent = Array(0...v)
func find(i: Int) -> Int {
if parent[i] == i {
return i
} else {
parent[i] = find(i: parent[i])
return parent[i]
}
}
func union(a: Int, b: Int) {
let num1 = find(i: a)
let num2 = find(i: b)
// 무조건 병합해야해.
if num1 < num2 {
parent[num2] = num1
} else {
parent[num1] = num2
}
}
// 2차원 배열로 세팅함.
for _ in 0..<e {
graph.append(readLine()!.split(separator: " ").map { Int($0)! })
}
graph.sort { $0[2] < $1[2] }
var result = 0
for element in graph {
let a = element[0]
let b = element[1]
let cost = element[2]
if find(i: a) != find(i: b) {
// 달라야 사이클이 아니다.
result += cost
// print(result)
union(a: a, b: b)
}
}
print(result)
}
}'알고리즘 문제 풀이' 카테고리의 다른 글
| [Swift] BOJ 23034 조별과제 멈춰! (실패: 시간초과) (0) | 2022.05.17 |
|---|---|
| [Swift] BOJ 4386 별자리 만들기 (0) | 2022.05.17 |
| [Swift] BOJ 1647 도시 분할 계획 (0) | 2022.05.16 |
| BOJ 1197 최소 스패닝 트리 (0) | 2022.05.16 |
| [Swift] BOJ 2143 두 배열의 합 (0) | 2022.05.13 |