๊ทธ๋ํ ํ์์ด๋?
๋ง์ ์์ ๋ฐ์ดํฐ๋ค ์ค์์ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๊ณผ์ ์ ํ์์ด๋ผ๊ณ ํ๋๋ฐ,
๊ทธ๋ํ์์ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๊ณผ์ ์ ๊ทธ๋ํ ํ์์ด๋ผ ๋ถ๋ฅธ๋ค.
๊ทธ๋ํ ํ์ ์๊ณ ๋ฆฌ์ฆ์๋ DFS, BFS๊ฐ ์๋ค.
DFS(Depth-First Search): ๊น์ด ์ฐ์ ํ์
BFS(Breadth-First Search): ๋๋น ์ฐ์ ํ์
๊น์ด ์ฐ์ ํ์(DFS)
๊น์ด ์ฐ์ ํ์ ์๊ณ ๋ฆฌ์ฆ์ ๊ทธ๋ํ์ ์์ ๋ฐ์ดํฐ์ ๋ค์ด๊ฐ ํ, ์์์ ์์ ๋ฐ์ดํฐ๋ฅผ ์์์ ์์์ ์์ ๋ฐ์ดํฐ๋ฅผ ๋ค์ด๊ฐ๋ ์์ผ๋ก, ํ ๊ฐ์ง๋ฅผ ๋๊น์ง ํ๊ณ ๋ค์ด๊ฐ์ ํ์ํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋ปํ๋ค.
ํ ์ค๊ธฐ๋ฅผ ๋๊น์ง ํ๊ณ ๋ ํ, ๋ค์ ์ค๊ธฐ๋ก ์ด๋ํด ๋ค์ ๋๊น์ง ํ๊ณ ๋๋ ๋ฐฉ์์ผ๋ก ์๋ํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
๋๋น ์ฐ์ ํ์(BFS)
๋๋น ์ฐ์ ํ์์ ์์ ๋ฐ์ดํฐ์์ ์์ ์ ์์ ๋ฐ์ดํฐ๋ค์ ๋ชจ๋ ํ์ํ๊ณ ๊ทธ๋ค์ ์์์ ์์ ๋ฐ์ดํฐ๋ค์ ๋ชจ๋ ํ์ธํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
1์ธต๋ถํฐ ์์ํด 2์ธต์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ํ์ธํ๊ณ , ๊ทธ๋ค์ 3์ธต์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ํ์ธํ๋ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํ์ํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
๊ทธ๋ํ ํ์ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ๊ธฐ
๊ทธ๋ํ ํ์ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋์ฒด๋ก ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ ์ด๋ค.
DFS์๋ Stack์,
BFS์๋ Queue๋ฅผ ์ฌ์ฉํ๋ค.
์คํ์ ์ด์ฉํ DFS ๊ตฌํ ๋ฐฉ๋ฒ(์ด๋ก )
์ด๊ธฐ์ ๋ค์๊ณผ ๊ฐ์ ๊ทธ๋ํ๊ฐ ์์ ๋,
์์์ ์ผ๋ก ์ง์ ํ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ๋จผ์ Stack์ ๋ฃ์ด ์ค๋ค.
๋ค์๊ณผ ๊ฐ์ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค.
Stack์์ ๋ฐ์ดํฐ๋ฅผ ๋นผ๋ธ๋ค.
๋นผ๋ธ ๋ฐ์ดํฐ์ ์ฐ๊ด๋์ด ์๋ child ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ํ์์ ์ฐพ์ ํ ์คํ์ ๋ฃ์ด ์ค๋ค(0์ child ๋ฐ์ดํฐ๋ 1์ด ๋๋ค).
์ฐ๊ด child ๋ฐ์ดํฐ๊ฐ ์๊ฑฐ๋, ์ด๋ฏธ ํ ๋ฒ ์คํ์ ๋ค์ด๊ฐ ๋ฐ์ดํฐ๋ ์คํ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ง ์๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋นผ๋ธ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅํ๋ค.
์ฃผ์ํ ์ ์ ํ ๋ฒ ์คํ์ ๋ค์ด๊ฐ ๋ฐ์ดํฐ๋ ๋ค์ ์คํ์ ๋ฃ์ง ์๋๋ค๋ ๊ฒ์ด๋ค.
์ 3๊ฐ์ง์ ๊ณผ์ ์ ์์๋๋ก ๋ฐ๋ณตํ๋ ๊ฒ์ด DFS ๊ตฌํ ๋ฐฉ๋ฒ์ด๋ค.
DFS๋ ์ฌ๊ท ํธ์ถ์ ํตํด ๋ ์ฝ๊ฒ ๊ทธ๋ํ๋ฅผ ์ํํ ์ ์๋ค.
ํ๋ฅผ ์ด์ฉํ BFS ๊ตฌํ(์ด๋ก )
์ด๊ธฐ์ ๋ค์๊ณผ ๊ฐ์ ๊ทธ๋ํ๊ฐ ์์ ๋,
DFS์ ๊ฐ์ด ์ด๊ธฐ์ ์์ํ ๋ฐ์ดํฐ๋ฅผ ๋จผ์ ํ์ ๋ฃ๊ณ ์์ํ๋ค.
๋ค์๊ณผ ๊ฐ์ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค.
ํ์์ ์ ์ผ ๋จผ์ ๋ค์ด๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋นผ์ค๋ค.
๋นผ๋ธ ๋ฐ์ดํฐ์ ์์ ๋ฐ์ดํฐ๋ค์ ๋ชจ๋ ํ์ ๋ฃ์ด์ค๋ค(๋ฐ์ดํฐ 2์ ์์ ๋ฐ์ดํฐ๋ 1, 3, 4์ด๋ค).
๋นผ๋ผ ์์ ๋ฐ์ดํฐ๊ฐ ์๊ฑฐ๋, ์ด๋ฏธ ํ ๋ฒ ํ์ ๋ค์ด๊ฐ ๋ฐ์ดํฐ๋ ํ์ ๋ฃ์ง ์๋๋ค.
๋นผ๋ธ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅํ๋ค.
DFS์ ๋๊ฐ์ด ํ์ ํ ๋ฒ ๋ค์ด๊ฐ ๋ฐ์ดํฐ๋ ๋ค์ ํ์ ๋ฃ์ด์๋ ์ ๋๋ค.
์์ ์์๋ ์ถ๋ฐ์ ์ 0์ผ๋ก ์ค์ ํ๊ณ ์์ํ์ง๋ง, ๊ผญ 0๊ณผ ๊ฐ์ ๋์๋ฝ ๋ฐ์ดํฐ๊ฐ ์๋์ด๋ ๋๋ค.
3๊ณผ 5 ๊ฐ์ ์ค์์ ๋ฐ์ดํฐ๋ฅผ ์์์ ์ผ๋ก ์ก์๋ DFS์ BFS๋ฅผ ๊ตฌํํ ์ ์๋ค.
์ฝ๋๋ก ๊ตฌํํ๊ธฐ
๋ฐฑ์ค์ 1260๋ฒ์ ์๋ก ๋ค์ด์ ์ฝ๋๋ก ๊ตฌํํด ๋ณด๊ฒ ๋ค.
์ฝ๋๋ก ๊ตฌํํ๊ธฐ ์ ์ ๊ฐ ๋ ธ๋ ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ํ๋ผ 2์ค ๋ฆฌ์คํธ์ ๊ฐ ๋ ธ๋์ ๋ฐฉ๋ฌธ ์ฌ๋ถ๋ฅผ ์ ์ ์๋ boolean ๋ฆฌ์คํธ๋ฅผ ์์ฑํ๋ค.
var visited = booleanArrayOf()
var graph = mutableListOf<MutableList<Int>>()
visited์๋ ๋ ธ๋์ ์๋งํผ size๋ฅผ ์ง์ ํด false ๋๋ true๋ก ๋ณ๊ฒฝํด ์ค ์์ ์ด๋ค.
graph๋ ๋ฐ๊นฅ ๋ฆฌ์คํธ์ size๋ ๊ฐ node์ ๊ฐ์๋งํผ์ผ๋ก ์ค์ ํ๋ค. ๋ด๋ถ์ ๋ฆฌ์คํธ์ size๋ ์ค์ ํ์ง ์๋๋ค.
๋ฆฌ์คํธ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋์ฌ ๊ฒ์ด๋ค.
[] // ๊ฐ 0์ ์ ์ ์ ์์
[2, 3, 4] // ๊ฐ 1์ ์ ์ ์ 2, 3, 4
[1, 4]
[1, 4]
[1, 2, 3]
์์ ๋ฆฌ์คํธ๋ graph ๋ฐ์ดํฐ์ ์์์ด๋ค. 0๋ฒ์งธ ์ค์ node 0์ ๊ด๊ณ๋ฅผ, 1๋ฒ์งธ ์ค์ node 1์ ๊ด๊ณ๋ฅผ ๋ปํ๋ค.
1๋ฒ์งธ ์ค์ 2, 3, 4๊ฐ ๋ค์ด ์๋๋ฐ, node 1์ node 2, 3, 4์ ๊ด๊ณ๋ฅผ ๋งบ๊ณ ์๋ค๋ ๋ป์ด๋ค.
DFS๋ ์คํ์ ์ด์ฉํ ์ฝ๋์ ์ฌ๊ท ์ฝ๋๋ฅผ ๋ณด์ฌ์ฃผ๊ฒ ๋ค.
๋จผ์ ์ฌ๊ท๋ฅผ ์ด์ฉํ dfs ํจ์์ด๋ค.
// ์ฌ๊ท ํจ์๋ฅผ ํตํ dfs ๊ตฌํ
private fun dfsRecursion(start: Int) {
visited[start] = true
val data = graph[start]
print("$start ")
for (node in data) {
if (!visited[node]) {
visited[node] = true
dfsRecursion(node)
}
}
}
์์์ ์ผ๋ก ์ค์ ํ ๋ฐ์ดํฐ๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ๋๋ค(start). start๋ฅผ ๊ธฐ์ ์ผ๋ก ํ์์ ์์ํ๋ค.
์์์ ์ ํด๋นํ๋ index์ visited๋ฅผ true๋ก ๋ฐ๊พผ๋ค(ํ ๋ฒ ๋ฐฉ๋ฌธํ๋ค๋ ๊ฒ์ ํ์).
graph์์ start๋ฒ์งธ index๋ฅผ ์ ์ฅํ๊ณ ์ฒ์์ ๋ฐ๋ start๋ฅผ ์ถ๋ ฅํ๋ค.
for๋ฌธ์ ๋๋ฉด์ node์ ํด๋น๋๋ visited๊ฐ false์ผ ๋๋ง ์ฌ๊ท ํธ์ถ์ ํด์ค๋ค.
๋ค์์ผ๋ก๋ ์คํ์ ์ด์ฉํ dfs ํจ์์ด๋ค.
// ์คํ์ ์ด์ฉํ dfs ๊ตฌํ
private fun dfs(start: Int) {
val stack: Stack<Int> = Stack()
stack.push(start)
visited[start] = true
while (stack.isNotEmpty()) {
val data = stack.pop()
for (node in graph[data]) {
if (!visited[node]) {
stack.push(node)
visited[node] = true
}
}
print("$data ")
}
}
์ฒ์์ start๋ฅผ ๋ฐ๋ ๊ฒ์ ๋๊ฐ๋ค.
๋ฐ์ดํฐ ์ํ์ฉ stack์ ์์ฑํ๊ณ , stack์ ์ฒซ ๋ฐ์ดํฐ์ธ start๋ฅผ ๋ฃ์ด์ฃผ๊ณ visited์ ์ฒดํฌ๋ฅผ ํด์ค๋ค.
๋ค์์ผ๋ก stack์ด ๋น ๋๊น์ง ๋ฐ๋ณตํ๋ค.
stack์ ๋ฐ์ดํฐ๋ฅผ ๋ฝ์์ data ๋ณ์๋ฅผ ๋ง๋ค๊ณ graph์ data๋ฒ์งธ ๊ฐ๊ณผ ๊ด๊ณ๋ฅผ ๋งบ๊ณ ์๋ ๋ชจ๋ node๋ฅผ for๋ฌธ์ผ๋ก ์ฒดํฌํ๋ค.
node๋ฒ์งธ visited๊ฐ false์ผ ๋๋ง stack์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ณ visited๋ฅผ true๋ก ๋ณ๊ฒฝํ๋ค.
for๋ฌธ์ ์ข ๋ฃํ๊ณ ์ฌ์ฉ๋ data๋ฅผ ์ถ๋ ฅํ๋ค.
BFS๋ ํ๋ฅผ ์ด์ฉํ ์ฝ๋๋ฅผ ๋ณด์ฌ ์ฃผ๊ฒ ๋ค.
ํ๋ฅผ ์ด์ฉํ bfs ํจ์์ด๋ค.
// ํ๋ฅผ ์ด์ฉํ bfs ๊ตฌํ
private fun bfs(start: Int) {
val queue: Queue<Int> = LinkedList()
queue.add(start)
visited[start] = true
print("$start ")
while (queue.isNotEmpty()) {
val data = queue.poll()
for (node in graph[data]) {
if (!visited[node]) {
queue.add(node)
visited[node] = true
print("$node ")
}
}
}
}
์คํ์ ์ด์ฉํ dfs์ ์ด๋ฐ์ ๋น์ทํ๋ค. ์คํ ๋์ ํ๋ฅผ ์ด๋ค๋ ๊ฒ์ด ๋ค๋ฅด๋ค.
ํ๋ฅผ ์์ฑํ๊ณ ์์์ ์ ํ์ ๋ฃ๊ณ visited์ ์ฒดํฌํ๋ค. ๊ทธ๋ฆฌ๊ณ start๋ฅผ ์ถ๋ ฅํ๋ค.
ํ๊ฐ ๋น ๋๊น์ง ๋ฐ๋ณตํ๋ค.
์คํ์์ ๊ฐ์ฅ ์ฒ์ ๋ค์ด๊ฐ ๋ฐ์ดํฐ์ธ data๋ฅผ ์์ฑํ๊ณ graph์ data๋ฒ์งธ ๊ฐ์ ๊ธฐ์ค์ผ๋ก for๋ฌธ์ผ๋ก ๋ฐ๋ณตํ๋ค.
node๋ฒ์งธ visited๊ฐ false์ด๋ฉด ํ์ ๊ฐ์ ๋ฃ๊ณ visited๋ฅผ ์ฒดํฌํ๊ณ ์ถ๋ ฅํ๋ค.
1260๋ฒ์ ์ ์ฒด ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค(์คํฌ ์ฃผ์)
import java.io.BufferedReader
import java.io.InputStreamReader
import java.util.LinkedList
import java.util.Queue
import java.util.Stack
var visited = booleanArrayOf()
// graph๋ ๊ฐ ๋
ธ๋์ ๊ด๊ณ๋ฅผ ๋ํ๋.
//[] // ๊ฐ 0์ ์ ์ ์ ์์
//[2, 3, 4] // ๊ฐ 1์ ์ ์ ์ 2, 3, 4
//[1, 4]
//[1, 4]
//[1, 2, 3]
var graph = mutableListOf<MutableList<Int>>()
fun main() = with(BufferedReader(InputStreamReader(System.`in`))) {
val (n, m, start) = readLine().split(" ").map { it.toInt() }
graph = MutableList(n+1) { mutableListOf() }
visited = BooleanArray(n+1)
for (i in 0 until m) {
val (relation1, relation2) = readLine().split(" ").map { it.toInt() }
graph[relation1].add(relation2)
graph[relation2].add(relation1)
}
// ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฌํด์ฃผ์ด์ผ ๋ฐ์ดํฐ๊ฐ ์ฌ๋ฐ๋ฅธ ์์๋๋ก ์ถ๋ ฅ๋จ
graph.map { it.sort() }
dfsRecursion(start)
println()
visited.fill(false)
bfs(start)
}
// ์ฌ๊ท ํจ์๋ฅผ ํตํ dfs ๊ตฌํ
private fun dfsRecursion(start: Int) {
visited[start] = true
val data = graph[start]
print("$start ")
for (node in data) {
if (!visited[node]) {
visited[node] = true
dfsRecursion(node)
}
}
}
// ์คํ์ ์ด์ฉํ dfs ๊ตฌํ
private fun dfs(start: Int) {
val stack: Stack<Int> = Stack()
stack.push(start)
visited[start] = true
while (stack.isNotEmpty()) {
val data = stack.pop()
for (node in graph[data]) {
if (!visited[node]) {
stack.push(node)
visited[node] = true
}
}
print("$data ")
}
}
// ํ๋ฅผ ์ด์ฉํ bfs ๊ตฌํ
private fun bfs(start: Int) {
val queue: Queue<Int> = LinkedList()
queue.add(start)
visited[start] = true
print("$start ")
while (queue.isNotEmpty()) {
val data = queue.poll()
for (node in graph[data]) {
if (!visited[node]) {
queue.add(node)
visited[node] = true
print("$node ")
}
}
}
}
1260๋ฒ์ ํ ๋, graph์ ๋ด๋ถ ๋ฆฌ์คํธ๋ฅผ ์ ๋ ฌํด ์ฃผ์ด์ผ ๋ฌธ์ ์์ ์ ์๋ง๊ฒ ์ถ๋ ฅ์ด ๋๋ค๋ ์ ๋ง ์ฃผ์ํ๋ฉด์ ํ๋ฉด ์ฝ๊ฒ ํด๊ฒฐํ ์ ์๋ค.
์ ๋ฆฌ
๊ทธ๋ํ ํ์ ์๊ณ ๋ฆฌ์ฆ์ ์ฝ๋ฉ ํ ์คํธ์ ์์ฃผ ๋์ค๋ ์ ํ์ ๋ฌธ์ ๋ผ๊ณ ํ๋ค.
2๊ฐ์ง์ ๊ทธ๋ํ ํ์ ์๊ณ ๋ฆฌ์ฆ ์ค ์์ ์ด ํธํ ๊ฒ์ ๊ตฌํํ๋ฉด ๋์ง๋ง, ์ด๋ค ๊ฒฝ์ฐ์๋ DFS๋ฅผ ์จ์ผ ํ๊ณ , ๋ ์ด๋ค ๊ฒฝ์ฐ์๋ BFS๋ฅผ ์จ์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ผ๋ฏ๋ก ๋ ๋ค ์์ ๋์ด์ผ ํ๋ค.
์๊ณ ๋ฆฌ์ฆ์ ์ด๋ป๊ฒ ์จ์ผ ํ๋์ง ์์์ผ๋, ๋ณธ๊ฒฉ์ ์ผ๋ก ๊ทธ๋ํ ๋ฌธ์ ๋ฅผ ํ์ด๋ณผ ์๊ฐ์ด๋ค.
์ถ์ฒ
https://jin1ib.tistory.com/entry/BFS-DFS-1
๊ทธ๋ํ ํ์ ์๊ณ ๋ฆฌ์ฆ(Graph Search Algorithm)
๊ทธ๋ํ ํ์ ๋ฌธ์ ๊ทธ๋ํ ํ์ ๋ฌธ์ ๋? ์ด๋ค ํ ๊ทธ๋ํ์ ํด๋น ๊ทธ๋ํ์ ์์ ์ ์ ์ด ์ฃผ์ด์ก์๋, ์์์ ์์ ๊ฐ์ (Edge, E)์ ํ๊ณ ์ด๋ํ ์ ์๋ ์ ์ (Vertex, V)๋ค์ ๋ชจ๋ ์ฐพ์์ผ ํ๋ ๋ฌธ์ ๋ฅผ ์
jin1ib.tistory.com
https://jason-api.tistory.com/133
๋ฐฑ์ค1260๋ฒ DFS ์ BFS ์ฝํ๋ฆฐ
https://www.acmicpc.net/problem/1260 1260๋ฒ: DFS์ BFS ์ฒซ์งธ ์ค์ ์ ์ ์ ๊ฐ์ N(1 ≤ N ≤ 1,000), ๊ฐ์ ์ ๊ฐ์ M(1 ≤ M ≤ 10,000), ํ์์ ์์ํ ์ ์ ์ ๋ฒํธ V๊ฐ ์ฃผ์ด์ง๋ค. ๋ค์ M๊ฐ์ ์ค์๋ ๊ฐ์ ์ด ์ฐ๊ฒฐํ๋
jason-api.tistory.com
https://velog.io/@daehoon12/%EB%B0%B1%EC%A4%80-1260-DFS%EC%99%80-BFS-Kotlin
[๋ฐฑ์ค 1260] DFS์ BFS (Kotlin)
[๋ฐฑ์ค 1260] DFS์ BFS (Kotlin)
velog.io
'๐ | Kotlin > ๐ค | ์๊ณ ๋ฆฌ์ฆ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๊ณ ๋ฆฌ์ฆ] ๋งค๊ฐ๋ณ์ ํ์(Parametric Search)๊ณผ ์ด๋ถ ํ์(Binary Search) (0) | 2024.06.26 |
---|---|
[์๊ณ ๋ฆฌ์ฆ] ๋งค๋ด์ฒ ์๊ณ ๋ฆฌ์ฆ(Manacher) ๊ฐ๋ (0) | 2024.06.24 |
[์๊ณ ๋ฆฌ์ฆ] ๊ทธ๋ฆฌ๋ ์๊ณ ๋ฆฌ์ฆ(Greedy Algorithm) (0) | 2024.06.18 |
[์๊ณ ๋ฆฌ์ฆ] ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ(Dynamic Programming) (0) | 2024.06.12 |
[Kotlin] ์ ํด๋ฆฌ๋ ํธ์ ๋ฒ ์๊ณ ๋ฆฌ์ฆ (0) | 2022.10.24 |