๐ก ํ์ด ๋ฐฉ๋ฒ
์ฐ๊ฒฐ๋ ๋ ธ๋๋ฅผ ์ ์ฅํ 2์ฐจ์ ๋ฐฐ์ด graph, ๋ฐฉ๋ฌธ์ฒ๋ฆฌ๋ฅผ ์ํ 1์ฐจ์ ๋ฐฐ์ด visited ์ด ํ์ํ๋ค.
DFS ๋ฅผ ํตํด ํธ๋ฆฌ๊ฐ ์๋์ง๋ฅผ ํ์ธํ๊ณ ํธ๋ฆฌ์ ๊ฐ์๋ฅผ ์ธ๋๋ฐ, ๋ ธ๋ ์ ์ฒด๋ฅผ ๋ฐฉ๋ฌธํ ์ ์๋๋ก ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋์ ๋ํด DFS ๋ฅผ ์ํํ๋ค.
๐ DFS ๊ณผ์ ์์ ํธ๋ฆฌ๊ฐ ์๋์ง ํ์ธํ๋ ๋ฐฉ๋ฒ์ ?!
๋ฌธ์ ์์ ์ฃผ์ด์ง "ํธ๋ฆฌ๋ ์ฌ์ดํด์ด ์๋ ์ฐ๊ฒฐ ์์์ด๋ค." ๋ฅผ ํตํด,, ํธ๋ฆฌ๋ฅผ ํ์ํ๋๋ฐ ์ฌ์ดํด์ด ์๊ธด๋ค๋ฉด, ํธ๋ฆฌ๊ฐ ์๋ ๊ฒ์์ ์ฒดํฌํ๋ค. graph ๋ฐฐ์ด์์๋ ์ฐ๊ฒฐ๋ ๋ ธ๋๋ฅผ ์ ์ฒด ์ ์ฅํ๋ฏ๋ก, ์ด์ ์ ๋ฐฉ๋ฌธํ ๋ ธ๋๋ฅผ ์ฌ์ดํด๋ก ์ธ์ํ ์ ๋ ์๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ค์ ๋ ธ๋์ ์ด์ ๋ ธ๋๊ฐ ๊ฐ์์ง ํ์ธํ๋ ์์ ์ ์ถ๊ฐํ๋ค. (์ด์ ๋ ธ๋ == ๋ค์ ๋ ธ๋) ๋ ์ด๋ฏธ ์ง๋์จ ๊ธธ์ด๋ฏ๋ก DFS ๋ฅผ ์ํํ์ง ์๊ณ ๋ฌด์ํ๋ค.
๐ ํธ๋ฆฌ์ ๊ฐ์๋ฅผ ์ธ๋ ๋ฐฉ๋ฒ ?!
DFS ๋ฅผ ์ํํด์ ๋ฐฉ๋ฌธ์ฒ๋ฆฌ๋ฅผ ํ๋๋ฐ, ๋ฐฉ๋ฌธ์ฒ๋ฆฌ ๋ฐฐ์ด ์ค ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋๊ฐ ์๋ค๋ฉด DFS ๋ฅผ ์ํํ๋ค. ์ ์ฒด ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธํ์ง ์๊ณ DFS ๊ฐ ์ข ๋ฃ๋์๋ค๋ ๊ฒ์ ํน์ ๋ ธ๋๊ฐ ๋๊ฒจ์๋ค๋ ๋ป์ด๋ค. ์ฌ๊ท์ ์ผ๋ก ํธ์ถ๋ DFS ์ธ์, ์ฒ์์ผ๋ก ํธ์ถ๋๋ DFS ๋ฅผ ์นด์ดํ ํ๋ฉด ํธ๋ฆฌ์ ๊ฐ์๋ฅผ ์ ์ ์๋ค.
๐ค ์ฃผ์ํด์ผํ ์
- ์ ๋ ฅ์ผ๋ก ๋ค์ด์ค๋ ๊ฐ์ ์ ์ฐ๊ฒฐ๋ ๋ ๋ ธ๋๋ ๊ฐ์ ์ ์๋ค. (๊ฐ์ ๋ ธ๋ ์ฐ๊ฒฐ -> ํธ๋ฆฌ๊ฐ ๋ง์)
- ํธ๋ฆฌ์ ๊ฐ์ ๊ฐ์๊ฐ 0์ธ ๊ฒฝ์ฐ๋ ์๋ค. (ํธ๋ฆฌ์ ์ ์ 6๊ฐ, ๊ฐ์ 0๊ฐ -> ํธ๋ฆฌ 6๊ฐ)
- ์ถ๋ ฅ ์์๋ฅผ ์ ๋ง์ถ์ ...
๐ฅ Swift ์ฝ๋
func DFS(prev: Int, curr: Int, graph: [[Int]], visited: inout [Bool]) -> Bool {
visited[curr] = true // ๋ฐฉ๋ฌธ์ฒ๋ฆฌ
for next in graph[curr] {
// ๋ค์๊ณผ ์ด์ ์ด ๊ฐ์ ๊ฒฝ์ฐ, ๊ฐ์ ๊ฒฝ๋ก๋ฅผ ๋ปํ๋ฏ๋ก ๋ฌด์
if next == prev {
continue
}
// next != prev, ์ด๋ฏธ ๋ฐฉ๋ฌธํ ๊ฒฝ์ฐ ์ฌ์ดํด์ด ์๊ธฐ๋ฏ๋ก ํธ๋ฆฌ๊ฐ ์๋
if visited[next] {
return false
}
// next != prev, ์ฌ์ดํด์ด ์๋ ๊ฒฝ์ฐ DFS ์ํ
// DFS ์ํ ๋์ค ์ฌ์ดํด์ด ์๊ธฐ๋ฉด false๊ฐ ๋ฐํ๋จ -> ์ฌ๊ท์ ์ผ๋ก false ๋ฐํ
if !DFS(prev: curr, curr: next, graph: graph, visited: &visited) {
return false
}
}
// DFS ์ํ ๋์ค ์ฌ์ดํด์ด ์๊ธฐ์ง ์์ผ๋ฉด true ๋ฐํ.
return true
}
func BOJ_4803() {
var i = 0
while true {
let line = readLine()!.split(separator: " ").map({Int($0)!})
let n = line[0], m = line[1]
if n == 0 && m == 0 { break }
i += 1
// ๊ทธ๋ํ์ ๋ฐฉ๋ฌธ์ฒ๋ฆฌ ๋ฐฐ์ด ์ด๊ธฐํ ๋ฐ ๋ฐ์ดํฐ ์
๋ ฅ ์ฒ๋ฆฌ
var graph: [[Int]] = Array(repeating: Array<Int>(), count: n+1)
var visited: [Bool] = Array(repeating: false, count: n+1)
for _ in 0..<m {
let line = readLine()!.split(separator: " ").map({Int($0)!})
graph[line[0]].append(line[1])
graph[line[1]].append(line[0])
}
var tree = 0 // ํธ๋ฆฌ์ ๊ฐ์
for node in 1...n {
if !visited[node] {
// ํด๋น ๋
ธ๋๋ฅผ ๋ฐฉ๋ฌธํ์ง ์์ ๊ฒฝ์ฐ์๋ง DFS ์ํ
if DFS(prev: 0, curr: node, graph: graph, visited: &visited) {
tree += 1 // ์ฌ์ดํด์ด ์๊ธฐ์ง ์์ ๊ฒฝ์ฐ ํธ๋ฆฌ์ ๊ฐ์ ์ฆ๊ฐ
}
}
}
if tree == 0 {
print("Case \(i): No trees.")
} else if tree == 1 {
print("Case \(i): There is one tree.")
} else{
print("Case \(i): A forest of \(tree) trees.")
}
}
}
BOJ_4803()