[Python/ํŒŒ์ด์ฌ][๐Ÿฅ‡3] ๋ฐฑ์ค€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ 9466 - ํ…€ ํ”„๋กœ์ ํŠธ

keyneneยท2022๋…„ 11์›” 3์ผ
0

Python

๋ชฉ๋ก ๋ณด๊ธฐ
21/26
post-custom-banner

๐Ÿ“–[Python/ํŒŒ์ด์ฌ][๐Ÿฅ‡3] ๋ฐฑ์ค€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ 9466 - ํ…€ ํ”„๋กœ์ ํŠธ

๐Ÿ“œ๋ฌธ์ œ



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

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

์ž„์˜์˜ ํ•œ ๋…ธ๋“œ์—์„œ ์‹œ์ž‘ํ•ด์„œ ๋‹ค์Œ ๋ถ„๊ธฐ๋กœ ๋„˜์–ด๊ฐ€๊ธฐ ์ „์— ํ•ด๋‹น ๋ถ„๊ธฐ๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•
#์žฌ๊ท€ #์ˆœํ™˜ #๋ฌดํ•œ๋ฃจํ”„ํƒˆ์ถœ #Back-Tracking


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

๋‚ด ํฌ์ŠคํŒ… : [Python/ํŒŒ์ด์ฌ][๐Ÿฅˆ1] ๋ฐฑ์ค€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ 14888 - ์—ฐ์‚ฐ์ž ๋ผ์›Œ๋„ฃ๊ธฐ
์ด์ „ ํฌ์ŠคํŒ…๊ณผ ๋น„์Šทํ•œ DFS์•Œ๊ณ ๋ฆฌ์ฆ˜ + ์ˆ˜์—ด ๋ฌธ์ œ์ด๋‹ค.

์šฐ์„  ํ…Œ์ŠคํŠธ์ผ€์ด์Šค๋งŒํผ ์‹คํ–‰๋˜๋ฏ€๋กœ ํ•˜๋‚˜์˜ ์ผ€์ด์Šค์˜ ๋™์ž‘์€ T๋งŒํผ ๋ฐ˜๋ณตํ•˜๋Š”for loof์•ˆ์—์„œ ๊ตฌํ˜„ํ•˜์ž
n, number(์„ ํƒ๋œํ•™์ƒ ๋ฆฌ์ŠคํŠธ)๋ฅผ ์ž…๋ ฅ๋ฐ›๊ณ , visited(list)์™€ result(list)๋ฅผ ์ž…๋ ฅ๋ฐ›์ž
i๊ฐ€ 1~n๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜๋Š” for loof์—์„œ visited[i] == False์ด๋ฉด dfs(v)๋ฅผ ์‹คํ–‰ํ•˜์ž
dfs(v)๋Š” ๋ฐฉ๋ฌธ์ฒ˜๋ฆฌ๋ฅผ ํ•จ๊ณผ ๋™์‹œ์— cycle์„ ์ด๋ฃจ๋Š” ํ•™์ƒ๋“ค์„ ๋ฐ˜ํ™˜ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„ํ•˜์ž


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

  1. n, number(์„ ํƒ๋œํ•™์ƒ ๋ฆฌ์ŠคํŠธ), visited(list), result(list)์ดˆ๊ธฐํ™”ํ•˜๊ณ ,
    ๋ฐฉ๋ฌธ ์•ˆ ํ•œ ๋…ธ๋“œ๋ฅผ dfs(i)๋กœ ํ˜ธ์ถœํ•˜์—ฌ cycle์ด ๋˜๋Š” ํ•™์ƒ๋ฆฌ์ŠคํŠธ๋ฅผ result์— ์ถ”๊ฐ€ํ•˜์ž

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

import sys
sys.setrecursionlimit(100000)
input = sys.stdin.readline

#cycle ์ด๋ฃจ๋Š” result ๋ฐ˜ํ™˜
def dfs(v):
    global result
    visited[v] = True
    cycle.append(v)
    num = number[v]

    if visited[num]:
        if num in cycle:
            result += cycle[cycle.index(num):]
        return
    else:
        dfs(num)

#ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋งŒํผ ์‹คํ–‰
for _ in range(int(input().rstrip())):
    N = int(input().rstrip())
    number = [0] + list(map(int, input().split()))
    visited = [True] + [False]*N
    result = []
	
    #1~n๊นŒ์ง€ ๋ฐฉ๋ฌธ์—ฌ๋ถ€ ํ™•์ธํ•˜๋ฉด์„œ dfs()ํ˜ธ์ถœ
    for i in range(1,N+1):
        if not visited[i]:
            cycle = []
            dfs(i)

    print(N-len(result))

โœ๏ธ1. ์ž…๋ ฅ๋ฐ›๊ณ , dfs()ํ•จ์ˆ˜, cycle๋ฆฌ์ŠคํŠธ ๊ตฌํ˜„

import sys
sys.setrecursionlimit(100000)
input = sys.stdin.readline

#cycle ์ด๋ฃจ๋Š” result ๋ฐ˜ํ™˜
def dfs(v):
    global result      #global์ด๋ฏ€๋กœ result dfs()๋ฐ–์œผ๋กœ ๋ฐ˜ํ™˜ ๊ฐ€๋Šฅ
    visited[v] = True  #๋ฐฉ๋ฌธ์ฒดํฌ
    cycle.append(v)    #cycle์— v์ถ”๊ฐ€
    num = number[v]    #num = v๊ฐ€ ์„ ํƒํ•œ ํ•™์ƒ

    if visited[num]:   #์„ ํƒ๋œ ํ•™์ƒ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ ์ ์ด ์žˆ์œผ๋ฉด
        if num in cycle:  #dfs()์—์„œ ๋งŒ๋“  ์ž„์‹œcycle์— num์ด ์žˆ๋Š”์ง€ ํ™•์ธ
            result += cycle[cycle.index(num):]  #result์— ์ž„์‹œcycle์ถ”๊ฐ€
        return
    else:
        dfs(num)  #์„ ํƒ๋œ ํ•™์ƒ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ ์ ์ž‰ ์—†์œผ๋ฉด dfs(์„ ํƒ๋œํ•™์ƒ)์‹คํ–‰

#ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋งŒํผ ์‹คํ–‰
for _ in range(int(input().rstrip())):
    N = int(input().rstrip())
    number = [0] + list(map(int, input().split()))
    visited = [True] + [False]*N
    result = []

	#1~n๊นŒ์ง€ ๋ฐฉ๋ฌธ์—ฌ๋ถ€ ํ™•์ธํ•˜๋ฉด์„œ dfs()ํ˜ธ์ถœ
    for i in range(1,N+1):
        if not visited[i]:
            cycle = [] #cycle ์ดˆ๊ธฐํ™” (๋งค ๋ฒˆํ˜ธ๋งˆ๋‹ค ํŒ€์ด ๋˜๋Š” ํ•™์ƒ์ด ๋‹ค๋ฅด๋‹ˆ๊นŒ)
            dfs(i)

    print(N-len(result))  #ํŒ€์ด ์•ˆ๊พธ๋ ค์ง„ ํ•™์ƒ ์ˆ˜ ์ถœ๋ ฅ

๐Ÿ“š๋™์ž‘์›๋ฆฌ ๋ฐ ์ •๋ฆฌ

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

import sys
sys.setrecursionlimit(100000)
input = sys.stdin.readline

def dfs(v):
    global result
    visited[v] = True
    cycle.append(v)
    num = number[v]

    if visited[num]:
        if num in cycle:
            result += cycle[cycle.index(num):]
        return
    else:
        dfs(num)

for _ in range(int(input().rstrip())):
    N = int(input().rstrip())
    number = [0] + list(map(int, input().split()))
    visited = [True] + [False]*N
    result = []

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

    print(N-len(result))

์ „ ์ฝ”๋“œ๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ํ›‘์–ด๋ณด์ž
ex)
n = 7
number = 3 1 3 7 3 4 6

for loof๋ถ€ํ„ฐ ์‚ดํŽด๋ณด๋ฉด,
 i = 1
 visited[1] = False์ด๋ฏ€๋กœ dfs(i)ํ˜ธ์ถœ
 ๐Ÿ‘‰๐Ÿป dfs(1)
    visited[1] = True
    cycle.append(1)     #์ž„์‹œ cycle = [1]
    num = number[1]     #num = 3
    
    if visited[3]:    #๋ฐฉ๋ฌธ์•ˆํ–ˆ์œผ๋ฏ€๋กœ X
    else dfs(3)
    
 ๐Ÿ‘‰๐Ÿป dfs(3)
 	visited[3] = True
    cycle.append(3)     #์ž„์‹œ cycle = [1,3]
    num = number[3]     #num = 3
    
    if visited[3]:    #๋ฐฉ๋ฌธํ–ˆ์œผ๋ฏ€๋กœ O
      if 3 in cycle:    #cycle์— 3 ์žˆ์œผ๋ฏ€๋กœ O
        result = cycle[cycle.index(3):]  #ํ˜„์žฌ ์ธ๋ฑ์Šค๋ถ€ํ„ฐ ๋๊นŒ์ง€ result์— ์ €์žฅ
        return
        

โ“cycle[cycle.index(3):]๋งŒ result์— ์ €์žฅํ•˜๋Š” ์ด์œ 

cycle์— [1,3]์ด ์žˆ๋Š”๋ฐ,
1์˜ number[1] = 3 / 3์˜ number[3] = 3 ์ด๋ฏ€๋กœ
3๋งŒ ํŒ€์„ ๊พธ๋ฆด ์ˆ˜ ์žˆ๊ณ , 1์€ ๊ทธ ๋ˆ„๊ฐ€ ์›ํ•ด๋„ ์ ˆ๋Œ€๋กœ ํŒ€์„ ๊พธ๋ฆฌ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


์ •๋ฆฌ

  1. list.index(x) : list์—์„œ์˜ x์˜ ์ธ๋ฑ์Šค(์ˆœ์„œ)๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
profile
keynene
post-custom-banner

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