Algorithm/BOJ
백준 2668 숫자고르기
삼쓰 웅쓰
2021. 6. 4. 23:05
728x90
출처: https://www.acmicpc.net/problem/2668
분류: 그래프, dfs
접근방식
1~n 까지에 각각 숫자가 매겨져 있을 때,
매겨진 숫자와 자신의 숫자의 집합이 같아지도록 최대한 많이 뽑아내는 문제입니다.
1~n을 노드 자신의 인덱스로, 매겨진 숫자를 다음 노드를 가리키는 그래프로 생각해보면,
결국 자기 자신으로 돌아오는 사이클이 아니면 절대 같은 집합이 될 수 없다는 걸 알 수 있습니다.
이렇게 각 사이클들을 더해주면 끝입니다 :)
전체 defaultVisit과 방문하면서 체크할 visit 배열을 만들어두고 탐색해서
사이클이 생겼다면 해당 visit을 defaultVisit으로 업데이트 시켜주는 방식으로 구현했습니다.
for i in 0..<n {
visit = defaultVisit
visit[i] = true
let nodesInCycle = hasCycle(current: graph[i], from: i, count: 1)
if nodesInCycle > 0 {
defaultVisit = visit
}
}
해결방법
let n = Int(readLine()!)!
var graph = [Int](repeating: 0, count: n)
for i in 0..<n {
let dest = Int(readLine()!)! - 1
graph[i] = dest
}
var defaultVisit = (0..<n).map { _ in false }
var visit = defaultVisit
func hasCycle(current idx: Int, from start: Int, count: Int) -> Int {
guard idx != start else { return count }
guard !visit[idx] else { return 0 }
visit[idx] = true
return hasCycle(current: graph[idx], from: start, count: count+1)
}
for i in 0..<n {
visit = defaultVisit
visit[i] = true
let nodesInCycle = hasCycle(current: graph[i], from: i, count: 1)
if nodesInCycle > 0 {
defaultVisit = visit
}
}
var result = [Int]()
for i in 0..<n {
if defaultVisit[i] {
result.append(i+1)
}
}
print(result.count)
result.forEach { print($0) }
배운점