Problem Solving/[ํ•ญํ•ด99] TIL

99ํด๋Ÿฝ ์ฝ”ํ…Œ ์Šคํ„ฐ๋”” 11์ผ์ฐจ TIL / DFS(๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰)

geum 2024. 11. 7. 16:03

โœ๏ธ ๋ฌธ์ œ

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

 

 

N๊ฐœ์˜ ์ •์ ๊ณผ M๊ฐœ์˜ ๊ฐ„์„ ์œผ๋กœ ์ด๋ฃจ์–ด์ง„, ์‚ฌ์ดํด์ด ์—†๋Š” ๋ฐฉํ–ฅ๊ทธ๋ž˜ํ”„(DAG)๊ฐ€ ์ฃผ์–ด์ง„๋‹ค.

ํˆฌ์–ด๋ฆฌ์ŠคํŠธ ๊ณฐ๊ณฐ์ด๋Š” ์ข…์ข… ์ด ๊ทธ๋ž˜ํ”„ ์œ„์—์„œ ์—ฌํ–‰์„ ๋– ๋‚œ๋‹ค. ํˆฌ์–ด๋ฆฌ์ŠคํŠธ ๊ณฐ๊ณฐ์ด์˜ ์—ฌํ–‰์€ 1๋ฒˆ ์ •์ ์—์„œ ์ถœ๋ฐœํ•ด ๊ฐ„์„ ์„ ๋”ฐ๋ผ์„œ ์ด๋™ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‹ค๊ฐ€ ๋” ์ด์ƒ ๊ฐ„์„ ์„ ๋”ฐ๋ผ์„œ ์ด๋™ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ํˆฌ์–ด๋ฆฌ์ŠคํŠธ์˜ ์—ฌํ–‰์€ ์ข…๋ฃŒ๋œ๋‹ค.

ํˆฌ์–ด๋ฆฌ์ŠคํŠธ ๊ณฐ๊ณฐ์ด์˜ ์—ด์„ฑ ํŒฌ์ธ ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด๋Š” ํˆฌ์–ด๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋‚˜๊ธฐ ์œ„ํ•ด ๊ทธ๋ž˜ํ”„ ์œ„์˜ ์ •์  ์ผ๋ถ€์—์„œ ์ž ๋ณตํ•˜๊ณค ํ•œ๋‹ค. ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด๊ฐ€ ์ž ๋ณตํ•œ ์ •์  ์œ„์— ํˆฌ์–ด๋ฆฌ์ŠคํŠธ ๊ณฐ๊ณฐ์ด๊ฐ€ ์„œ ์žˆ๊ฒŒ ๋˜๋ฉด ํˆฌ์–ด๋ฆฌ์ŠคํŠธ ๊ณฐ๊ณฐ์ด์™€ ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด๊ฐ€ ๋งŒ๋‚˜๊ฒŒ ๋œ๋‹ค.

์˜ค๋Š˜๋„ ํˆฌ์–ด๋ฆฌ์ŠคํŠธ ๊ณฐ๊ณฐ์ด๋Š” ์Œ์•…์„ ๋“ค์œผ๋ฉด์„œ ์—ฌํ–‰์„ ๋– ๋‚˜๋ ค๊ณ  ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‹ค๊ฐ€ Twice์˜ ๋…ธ๋ž˜์ธ "YES or YES" ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ€์‚ฌ๋ฅผ ๋“ฃ๊ฒŒ ๋œ๋‹ค.

์กฐ๊ธˆ ์‰ฝ๊ฒŒ ๋งํ•˜์ž๋ฉด
๋„Œ ๋ญ˜ ๊ณจ๋ผ๋„ ๋‚  ๋งŒ๋‚˜๊ฒŒ ๋  ๊ฑฐ์•ผ
Twice, YES or YES ๊ฐ€์‚ฌ ์ค‘ ์ผ๋ถ€

 

ํˆฌ์–ด๋ฆฌ์ŠคํŠธ ๊ณฐ๊ณฐ์ด๋Š” Twice์˜ ๋…ธ๋ž˜ ๊ฐ€์‚ฌ์ฒ˜๋Ÿผ, ๋ญ˜ ๊ณจ๋ผ๋„ ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด๋ฅผ ๋งŒ๋‚˜๊ฒŒ ๋  ๊ฒƒ์ธ์ง€ ๊ถ๊ธˆํ•ด์กŒ๋‹ค.

ํˆฌ์–ด๋ฆฌ์ŠคํŠธ ๊ณฐ๊ณฐ์ด๊ฐ€ ์–ด๋–ป๊ฒŒ ์ด๋™ํ•˜๋”๋ผ๋„ ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด๋ฅผ ๋งŒ๋‚˜๊ฒŒ ๋œ๋‹ค๋ฉด "Yes" ๋ฅผ, ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด๋ฅผ ๋งŒ๋‚˜์ง€ ์•Š๊ณ  ์ด๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•œ๋‹ค๋ฉด "yes" ๋ฅผ ์ถœ๋ ฅํ•˜์ž.

 

๐Ÿค– ์ž…์ถœ๋ ฅ ์˜ˆ์‹œ

 

๐Ÿง ๋‚œ์ด๋„/์†Œ์š” ์‹œ๊ฐ„

โœ… ๋‚œ์ด๋„: solved.ac ๊ธฐ์ค€ G4

โœ… ์†Œ์š” ์‹œ๊ฐ„: 1์‹œ๊ฐ„ 5๋ถ„

โœ… ๊ถŒ์žฅ ์‹œ๊ฐ„: 1์‹œ๊ฐ„ 15๋ถ„

 

๊ณ„์† ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ ๋‹ค๋ฅธ ๋ถ„ ์ฝ”๋“œ ํด๋ก  ์ฝ”๋”ฉํ•˜๋ฉด์„œ ์ œ์ถœํ•œ ๊ฑฐ๋ผ ํ˜ผ์ž ํž˜์œผ๋กœ ํ‘ผ ๊ฑด ์•„๋‹˜

 

๐Ÿ‘ฉ‍๐Ÿซ ์ฐธ๊ณ 

https://subinze.tistory.com/m/400

 

[๋ฐฑ์ค€/Python] 25195๋ฒˆ(DFS)_Yes or yes

๐Ÿ“Œ๋ฌธ์ œ ์œ ํ˜• DFS (๊ณจ๋“œ Lv.4) ๐Ÿ“Œ๋ฌธ์ œ 25195๋ฒˆ: Yes or yes ์ฒซ์งธ ์ค„์—๋Š” ์ •์ ์˜ ๊ฐœ์ˆ˜ $N$๊ณผ ๊ฐ„์„ ์˜ ๊ฐœ์ˆ˜ $M$์ด ์ฃผ์–ด์ง„๋‹ค. ($1 \leq N, M \leq 100\,000$) ์ดํ›„ $M$์ค„์— ๊ฑธ์ณ์„œ ๊ฐ„์„ ์˜ ์ •๋ณด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋‘ ์ •์ˆ˜ $u$, $v$

subinze.tistory.com

 

๐Ÿ’ก ํ’€์ด

1) ๋ฌธ์ œ ์œ ํ˜• ํŒŒ์•…

์ตœ์†Œ ํšŸ์ˆ˜, ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ์ƒ๊ฐํ•  ํ•„์š” ์—†์ด 1๋ฒˆ ๋…ธ๋“œ~๋ฆฌํ”„ ๋…ธ๋“œ๊นŒ์ง€์˜ ๊ฒฝ๋กœ๋ฅผ ํ•˜๋‚˜์”ฉ ๋‹ค ํ™•์ธํ•˜๋ฉด์„œ ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด์˜ ๋“ฑ์žฅ ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•˜๊ฒ ๊ตฌ๋‚˜ ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์–ด DFS๋ฅผ ๋– ์˜ฌ๋ ธ๋‹ค.

 

2) ๊ตฌํ˜„

์˜ค๋Š˜ ๋ฌธ์ œ๋Š” ์ฝ”๋“œ์— ๋ฐ”๋กœ ์ฃผ์„์„ ๋‹ฌ์•„์„œ ์„ค๋ช…์„ ๋Œ€์‹ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ์–ด๋–ป๊ฒŒ ํ’€์–ด์•ผ ํ• ์ง€ ๊ฐ์„ ์•„์˜ˆ ๋ชป ์žก์€ ์ •๋„๋Š” ์•„๋‹ˆ์—ˆ๋Š”๋ฐ ๊ตฌํ˜„์„ ๋ชปํ•ด์„œ ์ž๋ ฅ์œผ๋กœ ๋ชป ํ’€์—ˆ๋‹ค๋Š” ๊ฒŒ ๋„ˆ๋ฌด ์•„์‰ฝ๋‹ค.

 

import sys

# ์žฌ๊ท€ ๊นŠ์ด ๋” ๊นŠ๊ฒŒ ์„ค์ •
sys.setrecursionlimit(10**6)

input = sys.stdin.readline

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

# ๋‹จ๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„ ์ƒ์„ฑ
graph = {k: [] for k in range(1, N+1)}

for _ in range(M):
    u, v = map(int, input().split())
    
    graph[u].append(v)

S = int(input())

fanclub = list(map(int, input().split()))

# ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ์šฉ ๋ฐฐ์—ด
visited = [False]*(N+1)

def DFS(start_node):
    global flag # ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด๋ฅผ ๋งŒ๋‚ฌ๋Š”์ง€ ์ฒดํฌํ•˜๊ธฐ ์œ„ํ•œ ๋ณ€์ˆ˜(๊ธฐ๋ณธ ๊ฐ’์€ False)

    '''
    [์ข…๋ฃŒ ์กฐ๊ฑด 1] 
    ํ˜„์žฌ ํ™•์ธ ์ค‘์ธ ๋…ธ๋“œ๊ฐ€ ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด ๋…ธ๋“œ ๋ฆฌ์ŠคํŠธ์— ์†ํ•  ๊ฒฝ์šฐ ์ข…๋ฃŒ
    '''
    if start_node in fanclub:
        return
    
    visited[start_node] = True
    
    '''
    [์ข…๋ฃŒ ์กฐ๊ฑด 2]
    ์ด์ „์— ์ข…๋ฃŒ๋˜์ง€ ์•Š์•˜๊ณ  ํ˜„์žฌ ํ™•์ธ ์ค‘์ธ ๋…ธ๋“œ๊ฐ€ ๋ฆฌํ”„ ๋…ธ๋“œ์ผ ๊ฒฝ์šฐ ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด๋ฅผ ๋งˆ์ฃผ์น˜์ง€ ์•Š๋Š” ๊ฒฝ๋กœ๋กœ ์™”๋‹ค๋Š” ๋œป์ด๊ธฐ ๋•Œ๋ฌธ์— flag = True๋กœ ๋ฐ”๊พผ ํ›„ ์ข…๋ฃŒ
    '''
    if graph[start_node] == []:
        flag = True
        return
    
    # ์ด์ „์— ์ข…๋ฃŒ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ํ˜„์žฌ ํ™•์ธ ์ค‘์ธ ๋…ธ๋“œ(start_node)์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ(node) ํƒ์ƒ‰
    for node in graph[start_node]:
        # node๊ฐ€ ๋ฆฌํ”„ ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ๋ฉด์„œ ์•„์ง ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๊ณณ์ผ ๋•Œ DFS ์ˆ˜ํ–‰
        if graph[node] != [] and not visited[node]:
            DFS(node)
        # node๊ฐ€ ๋ฆฌํ”„ ๋…ธ๋“œ์ด๋ฉด์„œ ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด ๋…ธ๋“œ ๋ฆฌ์ŠคํŠธ์— ์†ํ•˜์ง€ ์•Š์„ flag = True๋กœ ๋ฐ”๊พผ ํ›„ ์ข…๋ฃŒ
        elif graph[node] == [] and node not in fanclub:
            flag = True
            return

flag = False

DFS(1)

# DFS๋ฅผ ๋‹ค ๋Œ์•˜์„ ๋•Œ flag = True๋ฉด ํŒฌํด๋Ÿฝ ๊ณฐ๊ณฐ์ด๋ฅผ ๋งŒ๋‚˜์ง€ ์•Š๋Š” ๊ฒฝ๋กœ๊ฐ€ ์žˆ๋‹ค๋Š” ๋œป
if flag:
    print("yes")
else:
    print("Yes")

 

 

4) ์–ด๋ ค์› ๋˜ ์ /๋ฐฐ์šด ์ 

๐Ÿšจ ์–ด๋ ค์› ๋˜ ์ 

  • ์ผ์ฐ ์ข…๋ฃŒํ•˜๊ธฐ ์œ„ํ•ด ํ˜„์žฌ ํ™•์ธ ์ค‘์ธ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๊ฐ€ ๋ฆฌํ”„ ๋…ธ๋“œ์ธ์ง€ ์•„๋‹Œ์ง€ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋– ์˜ฌ๋ฆฌ๋Š” ๊ฒŒ ์–ด๋ ค์› ๋‹ค. ์ฝ”๋“œ๋ฅผ ํ•œ ์ค„์”ฉ ์ฝ๋‹ค ๋ณด๋‹ˆ๊นŒ ์•„~ ํ•˜๊ฒŒ ๋๋˜ ๋ถ€๋ถ„์ด๋‹ค.

โ— ๋ฐฐ์šด ์ 

  • ๋นˆ return๋„ ์“ฐ์ผ ๋•Œ๊ฐ€ ์žˆ๋‹ค.
  • ์ฝ”๋“œ ์ฐธ๊ณ ํ–ˆ๋˜ ๋ถ„ ๋ธ”๋กœ๊ทธ๋ฅผ ๋‹ค์‹œ ๋ณด๋‹ค ๋ณด๋‹ˆ DFS์—์„œ์˜ return ์˜๋ฏธ์— ๋Œ€ํ•ด ์ข€ ๋” ์ฐพ์•„๋ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค.