[Algorithm | Python] ์ฝ๋ฉํ ์คํธ ๋๋น - BFS, DFS ๊ฐ๋ ์ ๋ฆฌ
DFS์ BFS
์๋ฃ๊ตฌ์กฐ๋ก ๊ฐ๋ ์ ์ตํ๋ค ํด๋ ์ฝ๋ฉํ ์คํธ ๋ฌธ์ ํ์ด์ ์ ์ฉํ๋ ๊ฒ์ด ์ฒ์์๋ ์ฝ์ง ์์๋ฐ, ๊ณ์ ํ๋ค ๋ณด๋ ์ ํ์ ์ธ ํ์ด ํจํด์ ๋ฐ๊ฒฌํ ์ ์์๋ค. ๋ฐ๋ผ์ ๊ธฐ๋ณธ์ ์ธ BFS, DFS ๊ตฌํ ์ฝ๋๋ฅผ ์ ๋ฆฌํด๋ณด๊ณ ์ ํ๋ค.
๐ ๊ฒฐ๊ตญ DFS, BFS์ ๊ธฐ๋ณธ ์๋ ์๋ฆฌ๋ ํ์ ์์ ๋ ธ๋ ๋ฐฉ๋ฌธ+๋ฐฉ๋ฌธ ์ฒ๋ฆฌ → ์ธ์ ๋ ธ๋ ๋ฐฉ๋ฌธ+๋ฐฉ๋ฌธ ์ฒ๋ฆฌ์ด๋ค. (*๋ฐฉ๋ฌธ ์ฒ๋ฆฌ๋ฅผ ํ๋ ์ด์ : ๊ฐ์ ๋ ธ๋๋ฅผ ์ค๋ณตํด์ ๋ฐฉ๋ฌธํ์ง ์๊ธฐ ์ํจ)
๐ ๋จ, LIFO(Last-In First-Out)์ธ stack๊ณผ stack memory๋ฅผ ํ์ฉํ๋ recursion(์ฌ๊ท) ↔ FIFO(First-In First-Out)์ธ queue์ ํน์ฑ์ด ๊ฐ๊ธฐ ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๊ท๊ฒฐ๋๋ค๊ณ ์ดํดํ๋ฉด ์ฝ๊ฒ ๋ค.
๊ฐ๋
DFS๋?
Depth-First Search : ๊น์ด ์ฐ์ ํ์
๊ธฐ๋ณธ ๋์ ๊ณผ์
- ํ์ ์์ ๋ ธ๋๋ฅผ ์คํ์ ์ฝ์ ํ๊ณ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
- ์คํ์ ์ต์๋จ ๋ ธ๋์ ๋ฐฉ๋ฌธํ์ง ์์ ์ธ์ ํ ๋ ธ๋๊ฐ ํ๋๋ผ๋ ์์ผ๋ฉด ๊ทธ ๋ ธ๋๋ฅผ ์คํ์ ๋ฃ๊ณ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌํ๋ค. ๋ฐฉ๋ฌธํ์ง ์์ ์ธ์ ๋ ธ๋๊ฐ ์์ผ๋ฉด ์คํ์์ ์ต์๋จ ๋ ธ๋๋ฅผ ๊บผ๋ธ๋ค.
- ๋ ์ด์ 2๋ฒ์ ๊ณผ์ ์ ์ํํ ์ ์์ ๋๊น์ง ๋ฐ๋ณตํ๋ค.
DFS๋ฅผ ์ ์ฉํ์ฌ ํ์ด์ผ ํ๋ ๋ฌธ์ ์ ํ
- ํ ์ ์ ๊ณผ ์ฐ๊ฒฐ๋ ๋ชจ๋ ์ ์ ํ์ํ๊ธฐ
- ๊ฒฝ๋ก ์ฐพ์๋ด๊ธฐ
- cycle์ด ์กด์ฌํ๋ ๊ฒฝ๋ก ์ฐพ๊ธฐ (BOJ 9466๋ฒ : ํ ํ๋ก์ ํธ)
BFS๋?
Breadth-First Search : ๋๋น ์ฐ์ ํ์
๊ธฐ๋ณธ ๋์ ๊ณผ์
- ํ์ ์์ ๋ ธ๋๋ฅผ ํ์ ์ฝ์ ํ๊ณ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌํ๋ค.
- ํ์์ ๋ ธ๋๋ฅผ ๊บผ๋ธ ๋ค์ ํด๋น ๋ ธ๋์ ์ธ์ ๋ ธ๋ ์ค์์ ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋๋ฅผ ๋ชจ๋ ํ์ ์ฝ์ ํ๊ณ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌํ๋ค.
- ๋ ์ด์ 2๋ฒ์ ๊ณผ์ ์ ์ํํ ์ ์์ ๋๊น์ง ๋ฐ๋ณตํ๋ค
BFS๋ฅผ ์ ์ฉํ์ฌ ํ์ด์ผ ํ๋ ๋ฌธ์ ์ ํ
- ์ต๋จ ๊ฑฐ๋ฆฌ ๊ตฌํ๊ธฐ
- ์ต๋จ ๊ฑฐ๋ฆฌ ๊ตฌํ๊ธฐ + ์กฐ๊ฑด ์ฌ๋ฌ ๊ฐ ์กด์ฌ (ex: ๋ฐฉ๋ฌธํ ์ง์ ๋ ๋ค์ ๋ฐฉ๋ฌธ ๊ฐ๋ฅ)
๊ฐ๋ ์ ์ฉํ์ฌ ๋ฌธ์ ํ๊ธฐ
DFS, BFS๋ฅผ ํ์ฉํ์ฌ ์ฌ์ด ๋ฌธ์ ๋ค์ ํ์ด๋ณธ๋ค.
๐ ๋ฌธ์ 1. ์๋ฃ์ ์ผ๋ ค ๋จน๊ธฐ
๋ฌธ์ ์ค๋ช
- N × M ํฌ๊ธฐ์ ์ผ์ ํ์ด ์๋ค. ๊ตฌ๋ฉ์ด ๋ซ๋ ค ์๋ ๋ถ๋ถ์ 0, ์นธ๋ง์ด๊ฐ ์กด์ฌํ๋ ๋ถ๋ถ์ 1๋ก ํ์๋๋ค.
๊ตฌ๋ฉ์ด ๋ซ๋ ค ์๋ ๋ถ๋ถ๋ผ๋ฆฌ ์, ํ, ์ข, ์ฐ๋ก ๋ถ์ด ์๋ ๊ฒฝ์ฐ ์๋ก ์ฐ๊ฒฐ๋์ด ์๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ๋ค.
์ด๋ ์ผ์ ํ์ ๋ชจ์์ด ์ฃผ์ด์ก์ ๋ ์์ฑ๋๋ ์ด ์์ด์คํฌ๋ฆผ์ ๊ฐ์๋ฅผ ๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ผ.
๋ค์์ 4 × 5 ์ผ์ ํ ์์์์๋ ์์ด์คํฌ๋ฆผ์ด ์ด 3๊ฐ๊ฐ ์์ฑ๋๋ค.
์ ๋ ฅ ์กฐ๊ฑด
- ์ฒซ ๋ฒ์งธ ์ค์ ์ผ์ ํ์ ์ธ๋ก ๊ธธ์ด N๊ณผ ๊ฐ๋ก ๊ธธ์ด M์ด ์ฃผ์ด์ง๋๋ค.(1 <= N, M <= 1,000)
- ๋ ๋ฒ์งธ ์ค๋ถํฐ N+1๋ฒ์งธ ์ค๊น์ง ์ผ์ ํ์ ํํ๊ฐ ์ฃผ์ด์ง๋๋ค.
- ์ด ๋ ๊ตฌ๋ฉ์ด ๋ซ๋ ค ์๋ ๋ถ๋ถ์ 0, ๊ทธ๋ ์ง ์์ ๋ถ๋ถ์ 1์ ๋๋ค.
์ถ๋ ฅ ์กฐ๊ฑด
- ํ ๋ฒ์ ๋ง๋ค ์ ์๋ ์์ด์คํฌ๋ฆผ์ ๊ฐ์๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
์ ๋ ฅ ์์
4 5
00110
00011
11111
00000
์ถ๋ ฅ ์์
3
๐ ํ์ด. DFS ํ์ฉ
# step 1. input ๋ฐ์์ ๊ทธ๋ํ ์์ฑํ๊ธฐ (input์ ์ง์ ๋ฐ์์ผ ํ๋ค.)
n, m = map(int, input().split())
graph = []
for i in range(n):
graph.append(list(map(int, input())))
# step 2. dfs ํจ์
def dfs(x, y):
if x <= -1 or x >= n or y <= -1 or y >= m: # x๊ฐ ๊ทธ๋ํ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๋
return False
if graph[x][y] == 0: # ๋
ธ๋์ ๋ฐ์ดํฐ๊ฐ์ด 0์ด๋ฉด == ๋ฐฉ๋ฌธ์ฒ๋ฆฌ๊ฐ ์ ๋์ด ์์ผ๋ฉด
graph[x][y] = 1 # ๋
ธ๋์ ๋ฐ์ดํฐ๊ฐ์ 1๋ก ํด์ค == ๋ฐฉ๋ฌธ์ฒ๋ฆฌ๋ฅผ ํจ
dfs(x-1, y) # ํด๋น ๋
ธ๋๋ถํฐ ์, ํ, ์ข, ์ฐ ์ฌ๊ท์ ์ ์ฉ
dfs(x, y-1)
dfs(x+1, y)
dfs(x, y+1)
return True
return False
# step 3. ๋ฌธ์ ํด๊ฒฐ
answer = 0
for j in range(n):
for k in range(m):
if dfs(j, k) == True:
answer += 1
print(answer)
๐ ๋ฌธ์ 2. ๋ฏธ๋ก ํ์ถ
๋ฌธ์ ์ค๋ช
- ๋๋น์ด๋ N × M ํฌ๊ธฐ์ ์ง์ฌ๊ฐํ ํํ์ ๋ฏธ๋ก์ ๊ฐํ๋ค. ๋ฏธ๋ก์๋ ์ฌ๋ฌ ๋ง๋ฆฌ์ ๊ดด๋ฌผ์ด ์์ด ์ด๋ฅผ
ํผํด ํ์ถํด์ผ ํ๋ค - ๋๋น์ด์ ์์น๋ (1, 1)์ด๋ฉฐ ๋ฏธ๋ก์ ์ถ๊ตฌ๋ (N, M)์ ์์น์ ์กด์ฌํ๋ฉฐ ํ ๋ฒ์ ํ ์นธ์ฉ ์ด๋ํ ์ ์๋ค.
์ด๋ ๊ดด๋ฌผ์ด ์๋ ๋ถ๋ถ์ 0์ผ๋ก, ๊ดด๋ฌผ์ด ์๋ ๋ถ๋ถ์ 1๋ก ํ์๋์ด ์๋ค. ๋ฏธ๋ก๋ ๋ฐ๋์ ํ์ถํ ์ ์๋
ํํ๋ก ์ ์๋๋ค - ์ด๋ ๋๋น์ด๊ฐ ํ์ถํ๊ธฐ ์ํด ์์ง์ฌ์ผ ํ๋ ์ต์ ์นธ์ ๊ฐ์๋ฅผ ๊ตฌํ๋ผ. ์นธ์ ์
๋๋ ์์ ์นธ๊ณผ ๋ง์ง๋ง ์นธ์
๋ชจ๋ ํฌํจํด์ ๊ณ์ฐํ๋ค
์ ๋ ฅ ์กฐ๊ฑด
- ์ฒซ์งธ ์ค์ ๋ ์ ์ N, M (4 <= N, M <= 200)์ด ์ฃผ์ด์ง๋๋ค. ๋ค์ N๊ฐ์ ์ค์๋ ๊ฐ๊ฐ M๊ฐ์ ์ ์ (0 ํน์ 1)๋ก ๋ฏธ๋ก์ ์ ๋ณด๊ฐ ์ฃผ์ด์ง๋๋ค. ๊ฐ๊ฐ์ ์๋ค์ ๊ณต๋ฐฑ ์์ด ๋ถ์ด์ ์ ๋ ฅ์ผ๋ก ์ ์๋ฉ๋๋ค. ๋ํ ์์ ์นธ๊ณผ ๋ง์ง๋ง ์นธ์ ํญ์ 1์ ๋๋ค.
์ถ๋ ฅ ์กฐ๊ฑด
- ์ฒซ์งธ ์ค์ ์ต์ ์ด๋ ์นธ์ ๊ฐ์๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
์ ๋ ฅ ์์
5 6
101010
111111
000001
111111
111111
์ถ๋ ฅ ์์
10
๐ ํ์ด 1. BFS ํ์ฉ
from collections import deque
n, m = map(int, input().split())
graph = []
for k in range(n):
graph.append(list(map(int, input())))
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
def bfs(x, y):
queue = deque()
queue.append((x, y))
while queue:
x, y = queue.popleft() # ๊ฐ ์ถ์ถ ๋ฐ queue์์ ์ ๊ฑฐ
for di in range(4):
nx = x + dx[di]
ny = y + dy[di]
if nx >= n or nx < 0 or ny >= m or ny < 0:
continue
if graph[nx][ny] == 0:
continue
if graph[nx][ny] == 1:
graph[nx][ny] = graph[x][y] + 1
queue.append((nx, ny))
return graph[n-1][m-1] # n,m์นธ = graph[n-1][m-1]
print(bfs(0, 0))
๐ ํ์ด 2. DFS ํ์ฉ
์ฌ์ค ์ด ๋ฌธ์ ๋ BFS์ ๋ํ์ ์ธ ๋ฌธ์ ์ง๋ง, queue๋ฅผ stack์ผ๋ก๋ง ๋ฐ๊พธ๋ฉด ์์ฃผ ๊ฐ๋จํ๊ฒ bfs๋ฅผ dfs๋ก ๋ฐ๊พธ์ด ํ ์ ์๋ค. ๋ค์์ ์ ๋ฌธ์ ๋ฅผ queue๊ฐ ์๋ stack์ ํ์ฉํ์ฌ ํธ๋ ๋ฐฉ๋ฒ์ด๋ค.
n, m = map(int, input().split())
graph = []
for k in range(n):
graph.append(list(map(int, input())))
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
def dfs(x, y):
stack = []
stack.append((x, y))
while stack:
x, y = stack.pop() # ๊ฐ ์ถ์ถ ๋ฐ stack์์ ์ ๊ฑฐ
for di in range(4):
nx = x + dx[di]
ny = y + dy[di]
if nx >= n or nx < 0 or ny >= m or ny < 0:
continue
if graph[nx][ny] == 0:
continue
if graph[nx][ny] == 1:
graph[nx][ny] = graph[x][y] + 1
stack.append((nx, ny))
return graph[n-1][m-1] # n,m์นธ = graph[n-1][m-1]
print(dfs(0, 0))
์ด๋ ๊ฒ BFS, DFS์ ๋ํ์ฌ ์ดํด๋ณด์๋ค. ๋จ, ์ค๋ ๊นจ๋ฌ์ ์ ์ DFS, BFS๋ฅผ ์ฒ์ ์ตํ๋ ์ ์ฅ์์๋ ๋จ์ํ ์ฝ๋๋ง ์ฝ๊ณ ์ดํดํ๋ ๊ฒ์ ํฐ ์๋ฏธ๊ฐ ์๋ค๋ ๊ฒ์ด๋ค. ํ๋ฃจ ๋ ์ก๊ณ ์ ๋๋ก ๋ช ๋ฌธ์ ์ฉ ํ๋ฉด์ ์ ํ์ ์ธ ์ฝ๋๋ฅผ ์ตํ๋ ๊ฒ์ด ๋ฌด์๋ณด๋ค ์ค์ํ ๋ฏ ํ๋ค.
์ฐธ๊ณ ์ฌ์ดํธ
- [์ฑ ] ์ด๊ฒ์ด ์ฝ๋ฉํ ์คํธ๋ค with Python
- myeongmy๋์ ๋ธ๋ก๊ทธ (https://myeongmy.tistory.com/55)