Problem Solving/[ν•­ν•΄99] TIL

99클럽 μ½”ν…Œ μŠ€ν„°λ”” 10일차 TIL / BFS(λ„ˆλΉ„ μš°μ„  탐색)

geum 2024. 11. 6. 14:47

✏️ 문제

https://www.acmicpc.net/problem/18352

 

μ–΄λ–€ λ‚˜λΌμ—λŠ” 1λ²ˆλΆ€ν„° Nλ²ˆκΉŒμ§€μ˜ λ„μ‹œμ™€ M개의 단방ν–₯ λ„λ‘œκ°€ μ‘΄μž¬ν•œλ‹€. λͺ¨λ“  λ„λ‘œμ˜ κ±°λ¦¬λŠ” 1이닀.

이 λ•Œ νŠΉμ •ν•œ λ„μ‹œ Xλ‘œλΆ€ν„° μΆœλ°œν•˜μ—¬ 도달할 수 μžˆλŠ” λͺ¨λ“  λ„μ‹œ μ€‘μ—μ„œ, μ΅œλ‹¨ 거리가 μ •ν™•νžˆ K인 λͺ¨λ“  λ„μ‹œλ“€μ˜ 번호λ₯Ό 좜λ ₯ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€. λ˜ν•œ 좜발 λ„μ‹œ Xμ—μ„œ 좜발 λ„μ‹œ X둜 κ°€λŠ” μ΅œλ‹¨ κ±°λ¦¬λŠ” ν•­μƒ 0이라고 κ°€μ •ν•œλ‹€.

예λ₯Ό λ“€μ–΄ N=4, K=2, X=1일 λ•Œ λ‹€μŒκ³Ό 같이 κ·Έλž˜ν”„κ°€ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€κ³  κ°€μ •ν•˜μž.

 

이 λ•Œ 1번 λ„μ‹œμ—μ„œ μΆœλ°œν•˜μ—¬ 도달할 수 μžˆλŠ” λ„μ‹œ μ€‘μ—μ„œ, μ΅œλ‹¨ 거리가 2인 λ„μ‹œλŠ” 4번 λ„μ‹œ 뿐이닀.  2번과 3번 λ„μ‹œμ˜ 경우, μ΅œλ‹¨ 거리가 1이기 λ•Œλ¬Έμ— 좜λ ₯ν•˜μ§€ μ•ŠλŠ”λ‹€.

 

πŸ€– μž…μΆœλ ₯ μ˜ˆμ‹œ

 

🧐 λ‚œμ΄λ„/μ†Œμš” μ‹œκ°„

βœ… λ‚œμ΄λ„: solved.ac κΈ°μ€€ S2

βœ… μ†Œμš” μ‹œκ°„: 14λΆ„ 49초

βœ… ꢌμž₯ μ‹œκ°„: 1μ‹œκ°„

 

πŸ’‘ 풀이

1) 문제 μœ ν˜• νŒŒμ•…

μž…μΆœλ ₯ μ˜ˆμ‹œμ™€ 'μ΅œλ‹¨ 거리' ν‚€μ›Œλ“œλ₯Ό 보고 BFS λ¬Έμ œλΌλŠ” 것을 μ•Œ 수 μžˆμ—ˆλ‹€. 9일차에 ν‘Ό λ¬Έμ œμ™€ λΉ„μŠ·ν•œ μœ ν˜•μΈ 것 κ°™μ•„ ν‘ΈλŠ” 데 어렀움은 μ—†μ—ˆλ‹€.

 

2) 아이디어 흐름

BFS κ΅¬ν˜„μ€ μ§€κΈˆκΉŒμ§€ ν‘Ό λ¬Έμ œλ“€κ³Ό 큰 차이가 μ—†κΈ° λ•Œλ¬Έμ— μƒλž΅ν•˜κ³  좜λ ₯ 쑰건을 μ²˜λ¦¬ν•˜λŠ” 뢀뢄에 λŒ€ν•΄μ„œ 정리해보렀고 ν•œλ‹€.

 

β‘  μ΅œλ‹¨ 거리 K인 λ„μ‹œκ°€ ν•˜λ‚˜λΌλ„ μžˆλŠ”μ§€ μ²΄ν¬ν•˜κΈ° μœ„ν•œ flag λ³€μˆ˜ μ‚¬μš©

μ΅œλ‹¨ 거리가 K인 λ„μ‹œκ°€ μ•„μ˜ˆ μ—†μœΌλ©΄ -1을 좜λ ₯ν•˜κ³  그렇지 μ•ŠμœΌλ©΄ λ„μ‹œ 번호λ₯Ό μ˜€λ¦„μ°¨μˆœμœΌλ‘œ 좜λ ₯ν•΄μ•Ό ν•˜λŠ” 것이 λ¬Έμ œμ—μ„œ μš”κ΅¬ν•œ 쑰건이닀.

 

flag = False둜 두고 visited 리슀트λ₯Ό λŒλ©΄μ„œ 값이 K+1인 μš”μ†Œκ°€ 있으면 flag = True둜 λ°”κΎΌ ν›„ break둜 for문을 νƒˆμΆœν•œλ‹€. visited 리슀트λ₯Ό λ‹€ λŒμ•˜λŠ”λ°λ„ flagκ°€ False라면 정닡은 -1이 되고  flagκ°€ Trueλ©΄ visited 리슀트λ₯Ό ν•œ 번 더 λŒλ©΄μ„œ 값이 K+1인 μš”μ†Œμ˜ 인덱슀λ₯Ό 좜λ ₯ν•˜λ©΄ λœλ‹€.

 

β‘‘ ⚠️ μ˜€λ¦„μ°¨μˆœμ˜ 함정 쑰심 ⚠️

μ²˜μŒμ— μ½”λ“œλ₯Ό μ œμΆœν–ˆμ„ λ•Œ 채점이 μ•„μ£Ό 쑰금 μ§„ν–‰λ˜λ‹€κ°€ κ°‘μžκΈ° ν‹€λ ΈμŠ΅λ‹ˆλ‹€κ°€ λ–΄λ‹€. 둜직 잘λͺ»λœ 뢀뢄이 μ—†λŠ”λ°? ν•˜λ˜ 쀑에 'μ˜€λ¦„μ°¨μˆœ'μ—μ„œ κΉ¨λ‹¬μŒμ„ μ–»λ‹€..!

 

# ν‹€λ¦° μ½”λ“œ
if not flag:
    print(-1)
else:
    for i, val in enumerate(sorted(visited)):
        if val == K+1:
            print(i)

 

λ¬Έμ œμ—μ„œ μ˜€λ¦„μ°¨μˆœμœΌλ‘œ 좜λ ₯ν•˜λΌκΈΈλž˜ μŠ΅κ΄€μ μœΌλ‘œ sortedλ₯Ό μ μš©ν•˜κ³  인덱슀λ₯Ό 좜λ ₯ν–ˆλ‹€.

 

...μƒκ°ν•΄λ³΄λ‹ˆκΉŒ K=2, visited=[0, 2, 3, 2]라고 ν•  λ•Œ 닡은 2인데 정렬을 ν•˜κ³  λ‚˜λ©΄ [0, 2, 2, 3]으둜 κΈ°μ‘΄ μˆœμ„œκ°€ κΉ¨μ§€κ²Œ λ˜μ–΄ 잘λͺ»λœ 인덱슀λ₯Ό 좜λ ₯ν•˜κ²Œ λ˜λŠ” 게 μ˜€λ‹΅μ˜ μ›μΈμ΄μ—ˆλ‹€.

 

3) κ΅¬ν˜„

import sys

from collections import deque

input = sys.stdin.readline

N, M, K, X = map(int, input().split())

country = {k: [] for k in range(1, N+1)}

for _ in range(M):
    A, B = map(int, input().split())
    
    country[A].append(B)

queue = deque([X])

visited = [0]*(N+1)

visited[X] = 1

while queue:
    city = queue.popleft()
    
    for node in country[city]:
        if visited[node] == 0:
            visited[node] = visited[city]+1
            
            queue.append(node)

flag = False

for dist in visited:
    if dist == K+1:
        flag = True
        break
    
if not flag:
    print(-1)
else:
    for i, val in enumerate(visited):
        if val == K+1:
            print(i)

 

4) μ–΄λ €μ› λ˜ 점/배운 μ 

🚨 μ–΄λ €μ› λ˜ 점

  • μ—†μŒ

❗ 배운 점

  • κ²½μš°μ— λ”°λΌμ„œλŠ” 쑰금만 μœ μ—°ν•˜κ²Œ μ‚¬κ³ ν•œλ‹€λ©΄ sort λ©”μ„œλ“œ, sorted ν•¨μˆ˜λ₯Ό 쓰지 μ•Šκ³ λ„ μ •λ ¬λœ 값을 좜λ ₯ν•  수 μžˆλ‹€ 😎