[Python/ํŒŒ์ด์ฌ] [๐Ÿฅˆ2] ๋ฐฑ์ค€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ 11724 - ์—ฐ๊ฒฐ ์š”์†Œ์˜ ๊ฐœ์ˆ˜

keyneneยท2022๋…„ 10์›” 30์ผ
1

Python

๋ชฉ๋ก ๋ณด๊ธฐ
16/26

๐Ÿ“–[Python/ํŒŒ์ด์ฌ][๐Ÿฅˆ2] ๋ฐฑ์ค€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ 11724 - ์—ฐ๊ฒฐ ์š”์†Œ์˜ ๊ฐœ์ˆ˜

๐Ÿ“œ๋ฌธ์ œ




DFS(๊นŠ์ด์šฐ์„ ํƒ์ƒ‰)

  • ์ž„์˜์˜ ํ•œ ๋…ธ๋“œ์—์„œ ์‹œ์ž‘ํ•ด์„œ ๋‹ค์Œ ๋ถ„๊ธฐ๋กœ ๋„˜์–ด๊ฐ€๊ธฐ ์ „์— ํ•ด๋‹น ๋ถ„๊ธฐ๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ์ž๊ธฐ ์ž์‹ ์„ ํ˜ธ์ถœํ•˜๋Š” ์žฌ๊ท€/์ˆœํ™˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํ˜•ํƒœ์ž„
  • ๋…ธ๋“œ ๋ฐฉ๋ฌธ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•ด๋†”์•ผ ๋ฌดํ•œ๋ฃจํ”„์— ๋น ์งˆ ์œ„ํ—˜์ด ์ค„์–ด๋“ฆ
  • ์ฃผ๋กœ ๋ฐฑํŠธ๋ž˜ํ‚น๊ณผ ํ•จ๊ป˜ ์“ฐ์—ฌ, ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋‹ค ๋ฐฉ๋ฌธํ•˜๋Š” ๊ฒƒ์„ ์ฐจ๋‹จํ•จ

๐Ÿ“•ํ’€์ด๋ฐฉํ–ฅ

"์—ฐ๊ฒฐ ์š”์†Œ์˜ ๊ฐœ์ˆ˜" ๋ผ๋Š” ๋ง์ด ์• ๋งคํ•ด์„œ ๊ฒ€์ƒ‰ํ•ด๋ณด๋‹ˆ, ๋งŒ๋“ค์–ด์ง€๋Š” "๊ทธ๋ž˜ํ”„์˜ ๊ฐœ์ˆ˜"์˜€๋‹ค

์šฐ์„  ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ map์œผ๋กœ ๋งŒ๋“ค๊ณ , visited ๋ฐฉ๋ฌธ๊ฒ€์‚ฌlist๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜์ž
dfs(idx)๋กœ ๋ฐฉ๋ฌธ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•˜์—ฌ, ๋ฐฉ๋ฌธํ•˜๋ฉด visited[idx]๋ฅผ 1๋กœ ๊ณ ์ณ์ฃผ๋ฉด์„œ idx๊ฐ€ ์ฆ๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ์นด์šดํŒ…(cnt+1) ํ•ด์ฃผ์ž
์žฌ๊ท€์ ์œผ๋กœ map์— ์žˆ๋Š” ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ–ˆ์„ ๋•Œ cnt๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ž


๐Ÿ“์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„์ˆœ์„œ

  1. n,m๊ณผ node๋ฅผ ์ž…๋ ฅ๋ฐ›์œผ๋ฉด์„œ amap์— mapํ˜•ํƒœ๋กœ ์ €์žฅํ•˜์ž
  2. visited list๋ฅผ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  dfs()ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ ,
    for loof๋ฅผ 1~n+1๊นŒ์ง€ ์ฆ๊ฐ€์‹œํ‚ค๋ฉฐ visited[i] == 0์ผ ๋•Œ dfs()๋ฅผ
    ํ˜ธ์ถœํ•˜์ž (for loofidx ์ฆ๊ฐ€ํ•  ๋•Œ๋งˆ๋‹ค ์นด์šดํŒ…)

๐Ÿ’ป๊ฒฐ๊ณผ์ฝ”๋“œ

import sys
input = sys.stdin.readline

n,m = map(int, input().split())
node = [list(map(int, input().split())) for _ in range(m)]
amap = [[] for _ in range(n+1)]

#amap์— ๊ทธ๋ž˜ํ”„ ํ˜•์‹์œผ๋กœ ๋„ฃ๊ธฐ
for u,v in node:
    amap[u].append(v)
    amap[v].append(u)

cnt = 0
visited = [0]*(n+1)
def dfs(v):
    visited[v] = 1
    for i in amap[v]:
        if not visited[i]:
            dfs(i)

for i in range(1, n+1):
    #visited[i] == 0์ผ๋•Œ๋งŒ dfs(i)์‹คํ–‰
    if not visited[i]:
        dfs(i)
        cnt += 1

print(cnt)

โœ๏ธ1. n, m, node ์ž…๋ ฅ๋ฐ›์œผ๋ฉด์„œ amap ์ €์žฅ

import sys
input = sys.stdin.readline

n,m = map(int, input().split())
node = [list(map(int, input().split())) for _ in range(m)]
amap = [[] for _ in range(n+1)]

for u,v in node:  #node์˜ [u, v]
    amap[u].append(v)  #node[u]์— v์ €์žฅ
    amap[v].append(u)  #node[v]์— u์ €์žฅ

โ“amap ์ €์žฅ ์›๋ฆฌ

ex. ์ž…๋ ฅ๊ฐ’์ด 1 2, 2 5 ์ธ ๊ฒฝ์šฐ

- node์— ์ž…๋ ฅ๋ฐ›์œผ๋ฉด์„œ ์ €์žฅ๋˜๋Š” ํ˜•ํƒœ
  node[0] = [1, 2]
  node[1] = [2, 5]
  โ€ปnode = [[1, 2], [2, 5]]
  
- for loof์—์„œ amap์— ์ €์žฅ๋˜๋Š” ํ˜•ํƒœ
  1. i == 0:
    amap[1].append(2)
    amap[2].append(1)
  2. i == 1:
    amap[2].append(5)
    amap[5].append(2)
    
  โ€ปamap[1] = 2
    amap[2] = 1, 5
    amap[5] = 2

โ— ์ž…๋ ฅ๊ฐ’์ด u โ†’ v ํ˜•ํƒœ๋กœ๋งŒ ๋“ค์–ด์˜ค๋‹ˆ๊นŒ, u โ†” vํ˜•ํƒœ๋กœ ์ €์žฅํ•ด์ค€๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ํŽธํ•จ
โ—โ— DFS, BFS ๋ฌธ์ œ ๋‹ค๋ฃฐ ๋•Œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋‹ˆ ๊ธฐ์–ตํ•ด๋‘์ž
(์Œ๋ฐฉํ–ฅ ์ธ๋ฑ์‹ฑ == ๊ทธ๋ž˜ํ”„)


โœ๏ธ2. dfs()ํ•จ์ˆ˜ ๊ตฌํ˜„๊ณผ for loof์—์„œ ํ˜ธ์ถœ

cnt = 0  #์—ฐ๊ฒฐ์š”์†Œ ๊ฐœ์ˆ˜ ์ €์žฅ
visited = [0]*(n+1)  #๋ฐฉ๋ฌธ์—ฌ๋ถ€ ๊ฒ€์‚ฌ

def dfs(v):
    visited[v] = 1
    for i in amap[v]:
        if not visited[i]:
            dfs(i)

for i in range(1, n+1):
    if not visited[i]:
        dfs(i)
        cnt += 1

print(cnt)

โ“์œ„ ์˜ˆ์ œ์—์„œ DFS ๋™์ž‘์›๋ฆฌ

visited = [0,0,0,0,0,0,0] 
(visited๋ฅผ n+1ํ•˜๋Š” ์ด์œ  : ๊ทธ๋ž˜ํ”„ ์ธ๋ฑ์‹ฑ์„ 1~n๊นŒ์ง€๋กœ ํ•ด์คฌ์œผ๋ฏ€๋กœ,
 ์‚ฌ์‹ค์ƒ visited[0]๊ฐ’์€ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.)

1. for loof์œผ๋กœ i๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋ฉด์„œ ๊ทธ๋ž˜ํ”„(amap)์˜ ์ธ๋ฑ์Šค๊ฐ€ i์ผ ๋•Œ,
   visited[i]๋กœ ์ธํ•ด i๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ–ˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
2. ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์•˜์œผ๋ฉด, dfs(i)๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ visited[i] = 1 ์ €์žฅํ•˜๊ณ ,
   i์ธ๋ฑ์Šค์˜ ๋…ธ๋“œ๋ฅผ ๋ชจ๋‘ ๊ฒ€์‚ฌํ•œ๋‹ค.


์ž˜ ๋ชจ๋ฅด๊ฒ ์œผ๋‹ˆ, ์˜ˆ์ œ 1๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด๋ณด์ž

   #amap[1] = 2, 5
   #amap[2] = 1, 5
   #visited = [0, 0, 0, 0, 0, 0, 0]์ธ ์ƒํ™ฉ
   
   for 1 in range(1, n+1):
     if not visited[1]:  #visited[1] == 0์ด๋ฏ€๋กœ True
       dfs(1)   #dfs(1)ํ˜ธ์ถœ
       cnt += 1   #์ด๊ฑด for i๊ฐ€ 1์ธ ์ƒํ™ฉ์ด ์ข…๋ฃŒ๋˜๋ฉด ์‹คํ–‰๋œ๋‹ค!!
       
   #dfs(1)๋™์ž‘
   def dfs(1):
     visited[1] = 1   #visited = [0, 1, 0, 0, 0, 0, 0]์ด ๋จ
     for i in amap[1]:   #amap[1]์ธ 2, 5๋ฅผ ํ•˜๋‚˜์”ฉ ๊ฒ€์‚ฌ
       if not visited[2]:   # visited[2] = 0์ด๋ฏ€๋กœ True
         dfs(2)   #dfs(2)ํ˜ธ์ถœ
         
   #dfs(2)๋™์ž‘
   def dfs(2):
     visited[2] = 1   #visited = [0, 1, 1, 0, 0, 0, 0]์ด ๋จ
     for i in amap[2]:   #amap[2]์ธ 1, 5๋ฅผ ํ•˜๋‚˜์”ฉ ๊ฒ€์‚ฌ
       if not visited[5]:   # visited[1] = 1์ด๋ฏ€๋กœ False
         dfs(5)   #dfs(5)ํ˜ธ์ถœ

   #dfs(5)๋™์ž‘
   def dfs(5):
     visited[5] = 1   #visited = [0, 1, 1, 0, 0, 1, 0]์ด ๋จ
     ...
     ...
     
   ๊ฒฐ๊ตญ ์ฒซ for loof์˜ i๊ฐ€ 1์ธ ์ƒํ™ฉ์ด ์ข…๋ฃŒ๋˜๋ฉด cnt += 1์ด ์‹คํ–‰๋˜์–ด
   [1,2,5]๋…ธ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์—ฐ๊ฒฐ๋…ธ๋“œ์ž„์ด ํ™•์ธ๋˜๊ณ , ์œ„ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•˜์—ฌ
   [3,4,6]๋…ธ๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์—ฐ๊ฒฐ๋…ธ๋“œ์ž„์ด ํ™•์ธ๋˜๋ฉด์„œ cnt +=1 ๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
   ๐Ÿ‘‰๐Ÿป ๊ฒฐ๊ณผ๋Š” cnt = 2 ์—ฐ๊ฒฐ๋…ธ๋“œ๋Š” 2๊ฐœ์ด๋‹ค

๐Ÿ“š์ •๋ฆฌ

โ“DFS ๋™์ž‘์›๋ฆฌ

๋ณดํ†ต DFS๋Š” ํ•œ ๋…ธ๋“œ๋ฅผ ์ค‘์ ์œผ๋กœ dfs(start, end, depth)ํ˜•ํƒœ๋กœ,
for loof์—์„œ i๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋ฉด์„œ dfs(i, end, depth)๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ
start == end ์ผ ๋•Œ depth๋ฅผ ์ €์žฅ or return ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋Œ€๋ถ€๋ถ„์ด๋‹ค.

#์ด๋Ÿฐ๋Š๋‚Œ
dfs(start, end, depth):

  if start == end:
    return depth
    
  for i in map[start]:
    dfs(i, end, depth)  #start๋ฅผ i๋กœ ์žก์•„์„œ ์žฌ๊ท€ํ•จ์ˆ˜๋กœ  ๋ฐ˜๋ณตํ˜ธ์ถœ

๊ทธ๋Ÿฌ๋‚˜ ์ด๋ฒˆ ์˜ˆ์ œ์™€ ๊ฐ™์ด, for loof์œผ๋กœ dfs()ํ˜ธ์ถœ ํšŸ์ˆ˜๋ฅผ ์กฐ์ ˆํ•˜๋Š” ์ผ์ข…์˜ Back-Tracking ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ, DFSํ˜ธ์ถœ์„ ์ค„์ด๋Š” ๋ฐฉ๋ฒ•์ด ์ผ๋ฐ˜์ ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค.

โœ๐Ÿป ๊ฒฐ๋ก ,

  • ์–ด๋Š๋ถ€๋ถ„์—์„œ DFS๋กœ ๊ฐ€์ง€์น˜๊ธฐ๋ฅผ ์ง„ํ–‰ํ• ์ง€,
  • ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค๋ถ€๋ถ„์„ Back-Tracking์œผ๋กœ ์ œ์•ฝ์„๊ฑธ์ง€ ๊ฐ€ ๊ด€๊ฑด์ด๋‹ค!
profile
keynene

0๊ฐœ์˜ ๋Œ“๊ธ€