๊ด€๋ฆฌ ๋ฉ”๋‰ด

DOing

[์•Œ๊ณ ๋ฆฌ์ฆ˜] DFS with Python ๋ณธ๋ฌธ

์•Œ๊ณ ๋ฆฌ์ฆ˜

[์•Œ๊ณ ๋ฆฌ์ฆ˜] DFS with Python

mangdo 2021. 5. 22. 10:37

๐Ÿ’ก DFS ์•Œ๊ณ ๋ฆฌ์ฆ˜

Depth-First Search, ๊ทธ๋ž˜ํ”„์—์„œ ๊นŠ์€ ๋ถ€๋ถ„์„ ์šฐ์„ ์ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.

๋ฐ์ดํ„ฐ์˜ ๊ฐฏ์ˆ˜๊ฐ€ N๊ฐœ์ธ ๊ฒฝ์šฐ, O(N)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„๋‹ค.

๐Ÿ’ก DFS ๋™์ž‘๊ณผ์ •

1. ํƒ์ƒ‰ ์‹œ์ž‘ ๋…ธ๋“œ๋ฅผ ์Šคํƒ์— ์‚ฝ์ž…ํ•˜๊ณ  ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค.

2. ์Šคํƒ์˜ ์ตœ์ƒ๋‹จ ๋…ธ๋“œ์— ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ธ์ ‘ ๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด, ๊ทธ ์ธ์ ‘๋…ธ๋“œ๋ฅผ ์Šคํƒ์— ๋„ฃ๊ณ  ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค.

๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ธ์ ‘๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด, ์Šคํƒ์—์„œ ์ตœ์ƒ๋‹จ ๋…ธ๋“œ๋ฅผ ๊บผ๋‚ธ๋‹ค.

3. 2๋ฒˆ๊ณผ์ •์„ ๋”์ด์ƒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•œ๋‹ค.

 

[์ฐธ๊ณ ]

๊ทธ๋ž˜ํ”„์˜ ๋‘ ๋…ธ๋“œ๊ฐ€ ๊ฐ€๋‚˜์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค๋ฉด '๋‘ ๋…ธ๋“œ๋Š” ์ธ์ ‘ํ•˜๋‹ค'๋ผ๊ณ  ํ‘œํ˜„ํ•œ๋‹ค.

DFS์—์„œ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ์ผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ์Šคํƒ์— ์–ด๋– ํ•œ ๋…ธ๋“œ๋ถ€ํ„ฐ ๋ฐฉ๋ฌธํ•  ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ๊ธฐ์ค€์ด ํ•„์š”ํ•˜๋‹ค. ์ด๋Š” ๋ฌธ์ œ๋งˆ๋‹ค ๋‹ค๋ฅผ ์ˆ˜๋„ ์žˆ๊ณ  ์ˆœ์„œ๊ฐ€ ์ƒ๊ด€์—†์„ ์ˆ˜ ์žˆ๋‹ค. ํ˜„์žฌ ํฌ์ŠคํŒ…์—์„œ๋Š” ๋‚ฎ์€ ์ˆ˜๋ถ€ํ„ฐ ๋ฐฉ๋ฌธํ•œ๋‹ค ๊ฐ€์ •ํ•œ๋‹ค.

๐Ÿ’ก DFS ๊ตฌํ˜„ ์ฝ”๋“œ

DFS๋Š” ์Šคํƒ ์ž๋ฃŒ๊ตฌ์กฐ์— ๊ธฐ์ดˆํ•œ๋‹ค๋Š” ์ ์—์„œ ๊ตฌํ˜„์ด ๊ฐ„๋‹จํ•˜๋‹ค.

์‹ค์ œ ๊ตฌํ˜„์€ ์Šคํƒ์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

def dfs(graph, n, visited):
  # ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ์ฒ˜๋ฆฌ
  visited[n] = True
  print(n, end='')
  
  # ํ˜„์žฌ ๋…ธ๋“œ์™€ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋ฅผ ํ™•์ธ
  for i in graph[n]:
    # ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋ผ๋ฉด
    if not visited[n]:
      # ์žฌ๊ท€ํ˜ธ์ถœ
      dfs(graph, i, visited)

######## dfs ์‚ฌ์šฉ
# ๊ฐ ๋…ธ๋“œ์— ์—ฐ๊ฒฐ๋œ ์ •๋ณด๋ฅผ 2์ฐจ์› ๋ฆฌ์ŠคํŠธ๋กœ ํ‘œํ˜„
graph =[
  [], # ๋…ธ๋“œ๋ฒˆํ˜ธ๊ฐ€ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ฑ์Šค 0์€ ๋น„์›Œ๋‘”๋‹ค
  [2,3,8], # 1๋ฒˆ ๋…ธ๋“œ์™€ ์ธ์ ‘ํ•œ ๋…ธ๋“œ 2,3,8
  [1,7],
  [1,4,5],
  [3,5],
  [3,4],
  [7],
  [2,6,8],
  [1,7]
]

# ๊ฐ ๋…ธ๋“œ๊ฐ€ ๋ฐฉ๋ฌธ๋œ ์ •๋ณด
visited = [False]*(8+1) # ์ „์ฒด ๋…ธ๋“œ๊ฐฏ์ˆ˜ 8๊ฐœ+์ธ๋ฑ์Šค0
# dfs ํ˜ธ์ถœ
dfs(graph, 1, visited)

 

๐Ÿ’ก DFS ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ

Q1. ์Œ๋ฃŒ์ˆ˜ ์–ผ๋ ค ๋จน๊ธฐ

 N*M ํฌ๊ธฐ์˜ ์–ผ์Œํ‹€์ด ์žˆ๋‹ค. ๊ตฌ๋ฉ์ด ๋šซ๋ ค ์žˆ๋Š” ๋ถ€๋ถ„์€ 0, ์นธ๋ง‰์ด๊ฐ€ ์กด์žฌํ•˜๋Š” ๋ถ€๋ถ„์€ 1๋กœ ํ‘œ์‹œ๋œ๋‹ค. ๊ตฌ๋ฉ์ด ๋šซ๋ ค์žˆ๋Š” ๋ถ€๋ถ„๋ผ๋ฆฌ ์ƒ,ํ•˜,์ขŒ,์šฐ๋กœ ๋ถ™์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค. ์ด๋•Œ ์–ผ์Œ ํ‹€์˜ ๋ชจ์–‘์ด ์ฃผ์–ด์กŒ์„ ๋•Œ ์ƒ์„ฑ๋˜๋Š” ์ด ์•„์ด์Šคํฌ๋ฆผ์˜ ๊ฐฏ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค. 

* ์ž…๋ ฅ ์กฐ๊ฑด

- ์ฒซ์งธ์ค„์— ์–ผ์Œ ํ‹€์˜ ์„ธ๋กœ ๊ธธ์ด N๊ณผ ๊ฐ€๋กœ๊ธธ์ด M์ด ์ฃผ์–ด์ง„๋‹ค.(1<= N,M <= 1000)

- ๋‘˜์งธ์ค„๋ถ€ํ„ฐ N+1๋ฒˆ์งธ ์ค„๊นŒ์ง€ ์–ผ์Œํ‹€์˜ ํ˜•ํƒœ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค.

- ์ด๋•Œ ๊ตฌ๋ฉ์ด ๋šซ๋ ค์žˆ๋Š” ๋ถ€๋ถ„์€ 0, ๊ทธ๋ ‡์ง€ ์•Š์€ ๋ถ€๋ถ„์€ 1์ด๋‹ค.

* ์ถœ๋ ฅ ์กฐ๊ฑด

- ํ•œ๋ฒˆ์— ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์•„์ด์Šคํฌ๋ฆผ์˜ ๊ฐฏ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

 

* ์ž…๋ ฅ ์˜ˆ์‹œ

4 5

00110

00011

11111

00000

* ์ถœ๋ ฅ ์˜ˆ์‹œ

3

 

[๋ฌธ์ œ ์•„์ด๋””์–ด]

 '์ƒ,ํ•˜,์ขŒ,์šฐ๋กœ ๋ถ™์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ์„œ๋กœ ์—ฐ๊ฒฐ๋˜์–ด์žˆ๋‹ค๊ณ  ๊ฐ„์ฃผํ•œ๋‹ค'์—์„œ DFS๋ฅผ ๋– ์˜ฌ๋ฆด ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋™์ž‘๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1. ํŠน์ •ํ•œ ์ง€์ ์˜ ์ƒ, ํ•˜, ์ขŒ, ์šฐ๋ฅผ ์‚ดํŽด๋ณธ ๋’ค์— ๊ฐ’์ด 0์ด๋ฉด์„œ ์•„์ง ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ง€์ ์ด ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ์ง€์ ์„ ๋ฐฉ๋ฌธํ•œ๋‹ค.

(=๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ธ์ ‘๋…ธ๋“œ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ฐฉ๋ฌธํ•œ๋‹ค.)

2. ๋ฐฉ๋ฌธํ•œ ์ง€์ ์—์„œ ๋‹ค์‹œ ์ƒ, ํ•˜, ์ขŒ, ์šฐ๋ฅผ ์‚ดํŽด๋ณด๋ฉด์„œ ๋ฐฉ๋ฌธ์„ ์ง„ํ–‰ํ•˜๋ฉด, ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ์ง€์ ์„ ๋ฐฉ๋ฌธํ•  ์ˆ˜ ์žˆ๋‹ค.

3. ์ „์ฒด ์–ผ์Œํ‹€์— ๋Œ€ํ•ด์„œ 1~2๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉฐ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์•„์ด์Šคํฌ๋ฆผ์˜ ๊ฐฏ์ˆ˜๋ฅผ ์„ผ๋‹ค.

 

[์ฝ”๋“œ]

๊ตฌํ˜„์‹œ, visited ๋ฆฌ์ŠคํŠธ๊ฐ€ ๊ตณ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.

graph๊ฐ€ 0, 1๋กœ๋งŒ ์ด๋ฃจ์–ด์ ธ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ visited๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

# ์„ธ๋กœn, ๊ฐ€๋กœm
n, m = map(int, input().split())

# 2์ฐจ์› ๋งต์ •๋ณด ์ž…๋ ฅ๋ฐ›๊ธฐ
graph=[]
for i in range(n):
  graph.append(list( map(int, input()) ))

# dfs๋กœ ํŠน์ •ํ•œ ๋ฐฉ๋ฌธํ•œ ๋’ค์— ์ธ์ ‘ ๋…ธ๋“œ๋“ค๋„ ๋ฐฉ๋ฌธ
def dfs(x,y):
  # ์ฃผ์–ด์ง„ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ ์‹œ์— ์ข…๋ฃŒ
  if x<0 or y<0 or x>n-1 or y>m-1:
    return False

  # ๋ฐฉ๋ฌธํ•  ์ˆ˜ ์žˆ๋Š” ๋…ธ๋“œ๋ผ๋ฉด ๋ฐฉ๋ฌธ
  if graph[x][y]==0:
    graph[x][y]=1 # ๋ฐฉ๋ฌธ์ฒ˜๋ฆฌ
  
    # ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋“ค(์ƒํ•˜์ขŒ์šฐ)์— ๋Œ€ํ•ด ๋ฐ˜๋ณต ์ˆ˜ํ–‰
    dfs(x-1,y) # ์ƒ
    dfs(x+1,y) # ํ•˜
    dfs(x,y-1) # ์ขŒ
    dfs(x,y+1) # ์šฐ
    return True

  return False

# ์•„์ด์Šคํฌ๋ฆผ ์ˆ˜ ์„ธ๊ธฐ
result = 0
for i in range(n):
  for j in range(m):
    # ํ˜„์žฌ ์œ„์น˜์—์„œ DFS ์ˆ˜ํ–‰
    # ์• ์ดˆ์— 1์ด์˜€๊ฑฐ๋‚˜ ๋ฐฉ๋ฌธํ•˜์—ฌ 1์ด๋˜์—ˆ๊ฑฐ๋‚˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚œ ๊ฒฝ์šฐ๋ผ๋ฉด
    # false๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.
    # ๋งŒ์•ฝ True๋ผ๋ฉด ์ด์ „์— ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ƒˆ๋กœ์šด ์•„์ด์Šคํฌ๋ฆผ์ด๋‹ค
    if dfs(i,j) == True:
      result +=1

print(result)

--> ์ถ”ํ›„์— ์ถ”๊ฐ€์˜ˆ์ •

๋”๋ณด๊ธฐ

๐Ÿ’ก DFS ๊ด€๋ จ ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค ๋ฌธ์ œ

Q1. ์™•์‹ค์˜ ๋‚˜์ดํŠธ

 

์™•์‹ค ์ •์›์€ ์ฒด์ŠคํŒ๊ณผ ๊ฐ™์€ 8*8์ขŒํ‘œ ํ‰๋ฉด์ด๋‹ค. ์™•์‹ค ์ •์›์˜ ํŠน์ •ํ•œ ํ•œ ์นธ์— ๋‚˜์ดํŠธ๊ฐ€ ์„œ์žˆ๋‹ค.  ๋‚˜์ดํŠธ๋Š” ์ด๋™ํ• ๋•Œ L์ž ํ˜•ํƒœ๋กœ๋งŒ ์ด๋™ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ •์› ๋ฐ–์œผ๋กœ๋Š” ๋‚˜๊ฐˆ ์ˆ˜ ์—†๋‹ค. ๋‚˜์ดํŠธ๋Š” ํŠน์ •ํ•œ ์œ„์น˜์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ 2๊ฐ€์ง€ ๊ฒฝ์šฐ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋‹ค.

1) ์ˆ˜ํ‰์œผ๋กœ ๋‘์นธ ์ด๋™ํ•œ ๋’ค์— ์ˆ˜์ง์œผ๋กœ ํ•œ์นธ ์ด๋™

2) ์ˆ˜์ง์œผ๋กœ ๋‘์นธ ์ด๋™ํ•œ ๋’ค์— ์ˆ˜ํ‰์œผ๋กœ ํ•œ์นธ ์ด๋™

 

์ด์ฒ˜๋Ÿผ 8*8์ขŒํ‘œ ํ‰๋ฉด์ƒ์—์„œ ๋‚˜์ดํŠธ ์œ„์น˜๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ ๋‚˜์ดํŠธ๊ฐ€ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค. ์ด๋•Œ ์™•์‹ค์˜ ์ •์›์—์„œ ํ–‰ ์œ„์น˜๋ฅผ ํ‘œํ˜„ํ•  ๋•Œ๋Š” 1๋ถ€ํ„ฐ 8๋กœ ํ‘œํ˜„ํ•˜๋ฉฐ, ์—ด ์œ„์น˜๋ฅผ ํ‘œํ˜„ํ•  ๋•Œ๋Š” a๋ถ€ํ„ฐ h๋กœ ํ‘œํ˜„ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋งŒ์•ฝ ๋‚˜์ดํŠธ๊ฐ€ a1์— ์žˆ์„ ๋•Œ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋Š” c2,b3 ๋‘๊ฐ€์ง€ ์ด๋‹ค. c2์— ์œ„์น˜ํ•ด ์žˆ๋‹ค๋ฉด ๊ฒฝ์šฐ์˜ ์ˆ˜๋Š” 6๊ฐ€์ง€ ์ด๋‹ค.

 

*์ž…๋ ฅ์กฐ๊ฑด

- ์ฒซ์งธ์ค„์— 8*8 ์ขŒํ‘œํ‰๋ฉด ์ƒ์—์„œ ํ˜„์žฌ ๋‚˜์ดํŠธ๊ฐ€ ์œ„์น˜ํ•œ ๊ณณ์˜ ์ขŒํ‘œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋‘๋ฌธ์ž๋กœ ๊ตฌ์„ฑ๋œ ๋ฌธ์ž์—ด์ด ์ž…๋ ฅ๋œ๋‹ค. ์ž…๋ ฅ๋ฌธ์ž๋Š” a1์ฒ˜๋Ÿผ ์—ด๊ณผ ํ–‰์œผ๋กœ ์ด๋ค„์ง„๋‹ค.

*์ถœ๋ ฅ ์กฐ๊ฑด

- ์ฒซ์งธ ์ค„์— ๋‚˜์ดํŠธ๊ฐ€ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜์‹œ์˜ค.

 

*์ž…๋ ฅ ์˜ˆ์‹œ

a1

*์ถœ๋ ฅ ์˜ˆ์‹œ

2

 

[๋ฌธ์ œ ์•„์ด๋””์–ด]

 ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ๋ฌธ์ œ์œ ํ˜•์ด๋‹ค. ์ƒํ•˜์ขŒ์šฐ์™€ ๋น„์Šทํ•œ ๋ฌธ์ œ์ธ๋ฐ, ์ขŒํ‘œ์„ค์ •์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.

์•„์Šคํ‚ค ์ฝ”๋“œ๋กœ 'a'๋Š” 97 ์ด๊ณ  'z'๋Š” 122์ž„์„ ์•Œ์•„๋‘์ž.

 

[์ฝ”๋“œ]

position = input()

# ์ด๋™๋ฐฉํ–ฅ ์ •์˜
move_col = [2, 2, -2, -2, 1, 1, -1, -1]
move_row = [1, -1, 1, -1, 2, -2, 2, -2]

# ์ด๋™ ๊ฐ€๋Šฅํ•œ ๋ฐฉํ–ฅ์˜ ๊ฐฏ์ˆ˜ ๊ตฌํ•˜๊ธฐ
count = 0
for i in range(len(move_col)):
  next_col = ord(position[0]) + move_col[i]
  next_row = int(position[1]) + move_row[i]

  # ํ•ด๋‹น ๋ฐฉํ–ฅ์œผ๋กœ ์ด๋™ ๊ฐ€๋Šฅ ์—ฌ๋ถ€
  if ord('a')<=next_col<=ord('h') and 1<=next_row<=8:
    count += 1

print(count)