본문 바로가기
백준/그래프 탐색

[백준] #11725 트리들의 부모 찾기 (python)

by 똥먹는낙타 2022. 4. 8.
728x90
반응형

11725번: 트리의 부모 찾기 (acmicpc.net)

 

11725번: 트리의 부모 찾기

루트 없는 트리가 주어진다. 이때, 트리의 루트를 1이라고 정했을 때, 각 노드의 부모를 구하는 프로그램을 작성하시오.

www.acmicpc.net

문제

루트 없는 트리가 주어진다. 이때, 트리의 루트를 1이라고 정했을 때, 각 노드의 부모를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 노드의 개수 N (2 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N-1개의 줄에 트리 상에서 연결된 두 정점이 주어진다.

출력

첫째 줄부터 N-1개의 줄에 각 노드의 부모 노드 번호를 2번 노드부터 순서대로 출력한다.

예제 입력 1 복사

7
1 6
6 3
3 5
4 1
2 4
4 7

예제 출력 1 복사

4
6
1
3
1
4

예제 입력 2 복사

12
1 2
1 3
2 4
3 5
3 6
4 7
4 8
5 9
5 10
6 11
6 12

예제 출력 2 복사

1
1
2
3
3
4
4
5
5
6
6

 

# Code

  • bfs 이용 - PyPy3로 제출
import sys
from collections import deque

input = sys.stdin.readline

n = int(input())
graph = [[] for _ in range(n+1)]

for _ in range(n-1):
    x, y = map(int, input().split())
    graph[x].append(y)
    graph[y].append(x)

visited = [False]*(n+1)
parents = [0] * (n+1)


def bfs(start):
    queue = deque([start])
    visited[start] = True
    while queue:
        v = queue.popleft()
        for i in graph[v]:
            if visited[i] == False:
                parents[i] = v
                queue.append(i)
                visited[i] = True    

bfs(1)

for i in range(2, n+1):
    print(parents[i])

 

  • dfs 이용 - Python3로 제출 (PyPy3로 dfs 제출할 경우 메모리 초과 발생)
import sys

input = sys.stdin.readline
sys.setrecursionlimit(1000000) # 파이썬의 recursionlimit가 더 늘려줌 / 그렇지 않으면 백준에서 recursionerror 발생

n = int(input())
graph = [[] for _ in range(n+1)]
parents = [0] * (n+1)

for _ in range(n-1):
    x, y = map(int, input().split())
    graph[x].append(y)
    graph[y].append(x)

def dfs(v):
    for i in graph[v]:
        if parents[i] == 0:
            parents[i] = v
            dfs(i)

dfs(1)

for i in range(2, n+1):
    print(parents[i])

# Comment

어렵지는 않았는데 채점할 때 제약? 때문에 짜증나는 문제였다. 
처음에 dfs로 재귀 사용해서 풀었는데, RecursionError가 발생해서 안되겠다 싶어서 일단 bfs로 풀었다. 
그런데 찾아보니까 파이썬이 정한 최대 재귀 깊이보다 재귀의 깊이가 더 깊어질 때 RecursionError가 발생한다고 한다. 
따라서 recursionlimit를 다시 정해줌으로써 이를 해결할 수 있다.

sys.setrecursionlimit(1000000)


📌 그런데 여기서 또 주의해야 할 점이 있다. 
나는 Python3로 제출하면 통과되지 않을 때 PyPy3로 제출하면 통과된 적이 많아서(속도가 더 빠르다고 알고있음) 항상 PyPy3로 제출하는데, 이 dfs의 경우 recursionlimit를 다시 정해주면 분명 해결된다고 했음에도 불구하고 PyPy3로 제출하면 이번에는 메모리 초과가 발생했다. Python3로 제출했을때서야 비로소 ... 맞았습니다가 떴다.... 정말 불편하다..

dfs로 다시 짤 때는 노드를 방문여부를 체크하는 visited 배열이 굳이 필요하지 않다는 것을 깨닫고 그냥 해당 노드의 부모만 저장하는 parents 배열만을 활용해서 parens[노드 번호] 의 값이 초기 값인 0일 경우에 여기에 부모 노드 값을 넣어주는 식으로 코드를 줄였다.

📌 알아둘 것!
간단한 코드 상에서는 Python3가 메모리, 속도 측면에서 우세
복잡한 코드(반복)을 사용하는 경우에는 PyPy3가 우세

Python3와 PyPy3의 차이에 대해서는 밑의 글을 참고했다.

[백준] 11725 트리의 부모 찾기 (velog.io)

728x90
반응형

댓글