๐ง ๋๋น ์ฐ์ ํ์ ( Breadth First Search )
๐ค ๋๋น์ฐ์ ํ์, BFS๋?
๋๋น ์ฐ์ ํ์, ์ฆ BFS๋ ๊ทธ๋ํ์ ์์ ํ์(Exhaustive Search)๊ธฐ๋ฒ ์ค ํ๋
- ๋๋น ์ฐ์ ํ์์ ํ์ ์์ ๋ ธ๋์ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ ธ๋๋ฅผ ์ฐ์ ํ์ํ๋ค.
- ์ด๋, ๋ชฉํ๋ ธ๋์ ๋์ฐฉํ๋ ๊ฒฝ๋ก๊ฐ ์ฌ๋ฌ๊ฐ๋ผ๋ฉด, ์ต๋จ๊ฒฝ๋ก๋ฅผ ๋ณด์ฅํ๋ค.
BFS๋ ๋ค์๊ณผ ๊ฐ์ ํน์ง์ด ์๋ค.
BFS๋ ์ ์ ์ ์ถ ๋ฐฉ์์ผ๋ก ํ์ํ๋ ๋ฐฉ๋ฒ์ด๊ธฐ์ ํ๋ฅผ ์ด์ฉํด ๊ตฌํํ๋ค.
๊ธฐ๋ฅ ํน์ง ์๊ฐ๋ณต์ก๋ G(V, E) ๊ทธ๋ํ์ ์์ ํ์ (Exhaustive Search) Queue ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ด์ฉํ FIFO ํ์ O(V+E)
๐ค BFS๋ฅผ ์์ฉํด ํ ์ ์๋ ๋ฌธ์
- ๊ฐ์ค์น๊ฐ ์๋ ๊ทธ๋ํ์ ์ต๋จ๊ฑฐ๋ฆฌ (๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ๊ณผ ๊ฐ์ด ์ต๋จ ๊ฒฝ๋ก ํ์ ์ ๋ง์ด ํ์ฉ)
๐ค BFS vs DFS
(์ด๋ค ์ํ์์์ ๋ต์ ๊ตฌํ๊ธฐ ์ํด ์ด๋ค ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ผ ๋๊น์ง ๋ค์ด๊ฐ๋ด์ผ ํ๋ ๊ฒฝ์ฐ์๋ BFS๋ก๋ ์ ์ ๋๋ค.
๋ง์ง๋ง๊น์ง ์ผ๋จ ๋ค์ด๊ฐ๋ค๊ฐ, ๋์์ค๋ ๊ธธ์ ๊ฑฐ์ณ๊ฐ๋ ์ ์ (vertex)๋ค์ ๋ํ ๋ต์ ์์ฐจ์ ์ผ๋ก ๊ฐฑ์ ํด์ค์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์๋ค.
๊ทธ๋ฆฌ๊ณ BFS๋ก ํ ์ ์๋ค๊ณ ํ๋๋ผ๋, DFS๊ฐ ํจ์ฌ ์ง๊ด์ ์ด๊ณ ๊ตฌํํ๊ธฐ ํธํ ๊ฒฝ์ฐ๋ค๋ ๋ฌด์ํ ์กด์ฌํ๋ค.)
๐ค BFS์ ํต์ฌ ์ด๋ก
BFS๋ ํ ๋ฒ ๋ฐฉ๋ฌธํ ๋ ธ๋๋ฅผ ๋ค์ ๋ฐฉ๋ฌธํ๋ฉด ์๋๋ค.
๋ฐ๋ผ์ ๋ ธ๋ ๋ฐฉ๋ฌธ์ฌ๋ถ๋ฅผ ์ฒดํฌํ ๋ฆฌ์คํธ๊ฐ ํ์ํ๋ค.
BFS ํ์๋ฐฉ์์ FIFOํน์ฑ์ ํ๋ฅผ ์ฌ์ฉํด ์ค๋ช ํ์๋ฉด, ์๋์ ๊ฐ๋ค.
1. BFS๋ฅผ ์์ํ ๋ ธ๋๋ฅผ ์ ํ ํ ์ฌ์ฉํ ์๋ฃ๊ตฌ์กฐ ์ด๊ธฐํ
- BFS๋ฅผ ์ํด ํ์ํ ์ด๊ธฐ ์์ ์๋์ ๊ฐ๋ค.
โฃ ์ธ์ ๋ฆฌ์คํธ๋ก ๊ทธ๋ํ๋ฅผ ํํ
โฃ ๋ฐฉ๋ฌธ๋ฆฌ์คํธ๋ฅผ ์ด๊ธฐํํ๊ธฐ
โฃ ์์ ๋ ธ๋ ์คํ์ ์ฝ์ ํ๊ธฐ
- ํ์ ์์๋ ธ๋๋ฅผ 1๋ก ์ฝ์ ํ ๋, ํด๋น ์์น์ ๋ฐฉ๋ฌธ๋ฆฌ์คํธ๋ฅผ ์ฒดํฌํ๋ฉด T, F, F, F, F, F ์ด๋ค.
2. ํ์์ ๋ ธ๋๋ฅผ ๊บผ๋ด ์ธ์ ๋ ธ๋๋ฅผ ๋ค์ ํ์ ์ฝ์
- ํ์์ ๋ ธ๋๋ฅผ ๊บผ๋ด๋ฉด์ ์ธ์ ๋ ธ๋๋ฅผ ํ์ ์ฝ์ ํ๋ค.
- ์ด๋, ๋ฐฉ๋ฌธ ๋ฆฌ์คํธ๋ฅผ ์ฒดํฌํ์ฌ ์ด๋ฏธ ๋ฐฉ๋ฌธํ ๋ ธ๋๋ ํ์ ์ฝ์ ํ์ง ์์ผ๋ฉฐ ๊บผ๋ธ ๋ ธ๋๋ ํ์์์์ ๊ธฐ๋กํ๋ค.
- ์ด๋, ๋ฐฉ๋ฌธ๋ฆฌ์คํธ๋ T, T, T, F, F, F ์ด๊ณ ํ์ ์์๋ 1์ด๋ค.
1์ ๊บผ๋ผ ๋ ํ์์์์ 1์ ๊ธฐ๋กํ๊ณ ์ธ์ ๋ ธ๋ 3, 2๋ฅผ ํ์ ์ฝ์ ํ๋ฉฐ ๋ฐฉ๋ฌธ๋ฆฌ์คํธ์ ์ฒดํฌํ๋ค.
3. ํ์ ๊ฐ์ด ์์ ๋๊น์ง ๋ฐ๋ณต
- ์์ ๊ณผ์ ์ ํ ์๋ฃ๊ตฌ์กฐ์ ๊ฐ์ด ์์ ๋๊น์ง ๋ฐ๋ณตํ๋ฉฐ ์ด๋ฏธ ๊ฑฐ์น ๋ ธ๋๋ ์ฌ์ฝ์ ํ์ง ์๋ ๊ฒ์ด ํต์ฌ!
- FIFO ๋ฐฉ์์ผ๋ก ํ์ํ๊ธฐ์ ํ์ ์์๊ฐ DFS์ ๋ค๋ฆ์ ์ ์ํด์ผ ํ๋ค!
- ์ด๋, ์ต์ข ์ ์ธ ํ์์์๋ 1 - 2 - 3 - 5 - 6 - 4 ์ด๋ค.
2, 3 ์์๋ก ๋ ธ๋๋ฅผ ๊บผ๋ด๋ฉฐ ์ธ์ ๋ ธ๋๋ฅผ ํ์ ์ฝ์ ํ๋ค.
2์ ๊ฒฝ์ฐ 5, 6์ ์์ง ๋ฐฉ๋ฌธํ์ง ์์๊ธฐ์ ๋ฐฉ๋ฌธ๋ฆฌ์คํธ๋ฅผ ์ฒดํฌํ๋ฉฐ ๋ชจ๋ ์ฝ์ ํ๋ค.
3์ ๊ฒฝ์ฐ 4 ์ญ์ ๋ฐฉ๋ฌธํ ์ ์ด ์์ด์ ๋ฐฉ๋ฌธ๋ฆฌ์คํธ๋ฅผ ์ฒดํฌํ๋ฉฐ ์ฝ์ ํ๋ค.
์ด๋, ํ์์์๋ 2, 3์ด ๊ธฐ๋ก๋๋ค.
5์ 6์ ๊บผ๋ผ ๋, ์ธ์ ๋ ธ๋๊ฐ ์๊ธฐ์ ํ์์์์ ๊ธฐ๋ก๋ง ํ๊ณ ๊บผ๋ธ๋ค.
4๋ฅผ ๊บผ๋ผ ๋ ์ธ์ ๋ ธ๋๋ 6์ด์ง๋ง ์ด๋ฏธ ์์ ๋ฐฉ๋ฌธํ๊ธฐ์ 6์ ์ฝ์ ํ์ง์๊ณ ๊บผ๋ด๊ธฐ๋ง ํ๋ค.
๐ค BFS ์๋์ฝ๋
BFS์ ๊ตฌํ
BFS๋ฅผ ๊ตฌํํ๋ ๊ฒฝ์ฐ์ ์๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
BFS(๋๋น ์ฐ์ ํ์)๋ ์์ ์ ์ (vertex)์ผ๋ก๋ถํฐ ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ๊น์ด ์ ์ ๋ค์ ๋จผ์ ์ฐจ๋ก๋ก ๋ฐฉ๋ฌธํ๊ณ
๋ฉ๋ฆฌ ๋จ์ด์ ธ ์๋ ์ ์ ์ ๋์ค์ ๋ฐฉ๋ฌธํ๋ ์ดํ ๋ฐฉ๋ฒ์ด๋ค. (์ ์ฐจ ์์ญ์ ๋ํ๋๊ฐ๋ค๊ณ ์๊ฐํ๋ฉด ์ฝ๋ค.)
BFS๋ DFS๋ณด๋ค ์ฐ์์๋ ์ ์ง๋ง, ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ๊ณผ ๊ฐ์ด ์ต๋จ ๊ฒฝ๋ก ํ์ ์ ๋ง์ด ํ์ฉ๋๋ค.
BFS๋ ์ฌ๊ท๋ก ๊ตฌํ๋์ง ์๊ณ ์ค์ง ํ๋ฅผ ์ด์ฉํ ๋ฐ๋ณต ๊ตฌ์กฐ๋ฅผ ํตํด ๊ตฌํ๋๋ค๋ ์ ์ ๋ช ์ฌํ์.
<pseudocode>
BFS(G, start_v)
let Q be a queue
mark start_v as visited
Q.enqueue(start_v)
while Q is not empty do
v := Q.dequeue()
if v is the goal then
return v
for all edges from v to w in G.adjacentEdges(v) do
if w is not marked as visited then
label w as visited
w.parent := v
Q.euqueue(w)
์๋์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด ํ๋์ ์ ์ ์ ๋ํ ์ธ์ ๊ฐ์ ์ ๋ชจ๋ ์ถ์ถํ๊ณ ๋์ฐฉ์ ์ธ ์ ์ ์ ํ์ ์ฝ์ ํ๋ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค.
์ฝ๋์ ์ ๊ฐ๋ ์์ DFS ์คํ ๊ตฌํ๊ณผ ํฌ๊ฒ ๋ค๋ฅด์ง ์๋ค.
๋ค๋ง, ์ฌ๊ธฐ์๋ FIFO ๊ตฌ์กฐ์ ํ๋ฅผ ํ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋น ์ฐ์ ํ์, ์ฆ ๊ฐ๊น์ด ์ ์ ๋ถํฐ ๋ชจ๋ ํ์ํด๋๊ณ ๊ทธ ๋ค์ ๊ฑฐ๋ฆฌ์ ์ ์ ์ผ๋ก ํ์ ๋ฒ์๋ฅผ ๋ํ๋๊ฐ๋ ์ดํ ๋ฐฉ์์ด ๊ฐ๋ฅํด์ง๋ ๊ฒ์ด๋ค.
<python code>
def bfs(start_v):
visited = [start_v]
Q = deque([start_v])
while Q:
v = Q.popleft()
for w in graph[v]:
if w not in visited:
visited.append(w)
Q.append(w)
return visited
ํจ์จ์ฑ
- ์์ ์ธ๊ธํ๋ DFS์ ๋ค๋ฅด์ง ์๋ค.
- ์๊ฐ ๋ณต์ก๋
์ธ์ ํ๋ ฌ์ ๊ฒฝ์ฐ ํ๋์ ์ ์ ๋น n๋ฒ check๋ฅผ ํด์ฃผ์ด์ผ ํ๊ธฐ ๋๋ฌธ์ O(n^2)์ด๋ค.
์ธ์ ๋ฆฌ์คํธ์ ๊ฒฝ์ฐ ์ ์ ๋ฐฉ๋ฌธ & ํด๋น ์ ์ ์ ์ธ์ ์ ์ ๋ฐฉ๋ฌธ์ด๋ฏ๋ก O(n+m)์ด๋ค.
์๊ฐ ๋ณต์ก๋์ ๊ฒฝ์ฐ์๋ ๊ฒฐ๊ตญ์ ์ด๋ค ์ ์ ์ ํ์ํ๋๋์ ๋ฌธ์ ์ด๊ธฐ ๋๋ฌธ์ ๊ณต๊ฐ ๋ณต์ก๋์ ๋์ผํ๋ค.
- ๊ณต๊ฐ ๋ณต์ก๋
๊ณต๊ฐ ๋ณต์ก๋์ ๊ฒฝ์ฐ, ๊ทธ๋ํ์ visited, ์คํ์ ๋ชจ๋ ๊ณ ๋ คํด์ฃผ์ด์ผ ํ๊ธฐ์ ๊ทธ๋ํ์ ๊ณต๊ฐ๋ณต์ก๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
์ธ์ ํ๋ ฌ์ ๊ฒฝ์ฐ์๋ ํ๋์ ์ ์ ๊ณผ ๋ชจ๋ ์ ์ ๊ฐ์ ์ฐ๊ฒฐ ๊ด๊ณ๋ฅผ ๋ค ํํํด์ฃผ์ด์ผ ํ๊ธฐ ๋๋ฌธ์ O(n^2)์ด๋ค.
์ธ์ ๋ฆฌ์คํธ์ ๊ฒฝ์ฐ์๋ ๊ทธ๋ํ ๋ด ์ ์ ๊ฐ์๋ฅผ n, ๊ฐ์ ๊ฐ์๋ฅผ m์ด๋ผ๊ณ ํ ๋ O(n+m)์ด๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก ๊ณต๊ฐ๋ณต์ก๋๋ ๊ทธ๋ํ์ ๊ณต๊ฐ๋ณต์ก๋๋ฅผ ๋ฐ๋ผ ๊ฐ๊ฒ ๋๋ค.
BFS์ ํจ์จ์ฑ์ ๋ํด ๋งํ ๊ฒฝ์ฐ, ์คํ๊ณผ visited๋ ๋ชจ๋ O(n)์ ๊ณต๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๊ณ ์๋ค (์ ์ ๊ฐ์ n).
์ด๋ ๊ทธ๋ํ๊ฐ ์ธ์ ํ๋ ฌ์ด๋ ์ธ์ ๋ฆฌ์คํธ๋ก ๊ตฌํ๋์ด ์๋ ๋ ๊ฐ์ง ๊ฒฝ์ฐ ๋ชจ๋์ ํด๋นํ๋ค.
๐ง ๋ฐฑ์ค 1260 (DFS์ BFS)
๐ค Algorithm ๊ณผ์ _ DFS
1. ๊ทธ๋ํ๋ฅผ ์ธ์ ๋ฆฌ์คํธ๋ก ์ ์ฅํ๋ค. (๋ฌด๋ฐฉํฅ ๊ทธ๋ํ์ด๊ธฐ์ ์์ชฝ๋ฐฉํฅ์ผ๋ก ๊ฐ์ ์ ๋ชจ๋ ์ ์ฅํ๋ค.)
2. ๋ฐฉ๋ฌธ๋ฆฌ์คํธ๋ฅผ ๋ชจ๋ False๋ก ์ด๊ธฐํํ๋ค.
3. ์ฌ๊ท๋ฅผ ์ด์ฉํ DFS๋ฅผ ์ํํ๋๋ฐ, ์๋์ ๊ฐ์ด ์งํํ๋ค.
๐ค Algorithm ๊ณผ์ _ BFS
1. ๊ทธ๋ํ๋ฅผ ์ธ์ ๋ฆฌ์คํธ๋ก ์ ์ฅํ๋ค. (๋ฌด๋ฐฉํฅ ๊ทธ๋ํ์ด๊ธฐ์ ์์ชฝ๋ฐฉํฅ์ผ๋ก ๊ฐ์ ์ ๋ชจ๋ ์ ์ฅํ๋ค.)
2. ๋ฐฉ๋ฌธ๋ฆฌ์คํธ๋ฅผ ๋ชจ๋ False๋ก ์ด๊ธฐํํ๋ค. (์ด๋, ์์ DFS์์ ์ฌ์ฉํ๊ธฐ์ ์ด๊ธฐํ๋ฅผ ๋ฐ๋์ ํด์ค์ผ ํ๋ค!)
3. BFS๋ฅผ ์ํํ๋๋ฐ, ์๋์ ๊ฐ์ด ์งํํ๋ค.
์ด๋ฅผ ํ์ดํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
1. ํ ์๋ฃ๊ตฌ์กฐ์ starting_vertex ์ฝ์ visit_list์ ํ์ฌ vertex ๊ธฐ๋ก 2. while (ํ๊ฐ ๋น ๋ ๊น์ง): ํ์์ vertex๋ฅผ ๊ฐ์ ธ์ ์ถ๋ ฅ ํ์ฌ vertex์ ์ฐ๊ฒฐvertex ์ค ๋ฏธ๋ฐฉ๋ฌธ vertex๋ฅผ ํ์ ์ฝ์ (append) ๋ฐฉ๋ฌธ๋ฆฌ์คํธ์ ๊ธฐ๋ก
๐คซ solution_1260import sys input = sys.stdin.readline V, E, starting_vertex = map(int, input().split()) # graph๋ผ๋ ์ธ์ ๋ฆฌ์คํธ ์์ฑ # [1] [2] [3] [4] # [[], [2, 3, 4], [1, 4], [1, 4], [1, 2, 3], []] graph = [[] for _ in range(V+1)] for _ in range(E): u, v = map(int, input().split()) graph[u].append(v) graph[v].append(u) # ์ ์ ์ ์ฐ์ ์์๊ฐ ๋ถ์ฌ๋์์ผ๋ฏ๋ก ์ ๋ ฌ for i in range(V+1): graph[i].sort() # ๋ฐฉ๋ฌธ๋ฆฌ์คํธ ์์ฑ visit_list = [False] * (V+1) def DFS(v): print(v, end = " ") visit_list[v] = True for i in graph[v]: if not visit_list[i]: DFS(i) from collections import deque def BFS(v): queue = deque() queue.append(v) visit_list[v] = True while queue: curr_vertex = queue.popleft() print(curr_vertex, end = " ") for i in graph[curr_vertex]: if not visit_list[i]: visit_list[i] = True queue.append(i) # DFS ์ถ๋ ฅ DFS(starting_vertex) print() visit_list = [False] * (V+1) # ๋ฆฌ์คํธ ์ด๊ธฐํ # BFS ์ถ๋ ฅ BFS(starting_vertex)