문제 요약
| 항목 | 설명 |
|---|---|
| 입력 | 노드 수 N, 그리고 N-1개의 간선 정보 |
| 중요 | 간선은 부모→자식 방향이 아니라 그냥 연결 정보 |
| 루트 | 1번 노드를 루트로 고정 |
| 출력 | 2번 노드부터 N번 노드까지의 부모 노드 번호 |
문제에서 주어지는 간선은 “누가 부모인지”를 알려주는 것이 아니라 “두 노드가 연결되어 있다”는 정보입니다. 그래서 반드시 1번에서 시작해 탐색하며 부모를 정해야 합니다.
가장 많이 헷갈리는 부분
헷갈림 포인트
예제 입력에 1 6, 4 1 같은 줄이 섞여 있으니까 “그럼 1의 부모가 6인가?”, “왜 출력에서 부모가 1인 노드가 여러 개 나오지?” 하고 헷갈리기 쉽습니다.
정답 해석
1 6은 “1이 6의 부모다”가 아닙니다.
그냥 1번 노드와 6번 노드가 연결되어 있다는 뜻입니다.
부모 관계는 입력 순간에 정해지는 것이 아니라, 1을 루트로 잡고 DFS/BFS로 따라가면서 정해집니다.
예제 1 시각화
예제 입력의 간선
1 - 6
6 - 3
3 - 5
4 - 1
2 - 4
4 - 7
6 - 3
3 - 5
4 - 1
2 - 4
4 - 7
이건 방향이 없는 연결 정보입니다. 아직 부모/자식은 정해지지 않은 상태입니다.
1을 루트로 놓고 펼치면
1
/ \
6 4
|
/ \
3
|
52 7
왜 1이 두 번 나오나?
4의 부모도 1이고, 6의 부모도 1이기 때문입니다. 부모가 1인 노드가 여러 개 있는 것은 전혀 이상하지 않습니다. 한 부모가 여러 자식을 가질 수 있기 때문입니다.
핵심 아이디어
1. 입력은 부모 정보가 아니다
간선 입력 a b는 a와 b가 연결되어 있다는 뜻입니다. 따라서 바로 parent[a] = b처럼 저장하면 안 됩니다.
2. 먼저 그래프를 만든다
무방향 트리이므로 인접 리스트를 만들 때는 graph[a].append(b), graph[b].append(a) 둘 다 해줘야 합니다.
3. 1번부터 탐색하면서 부모를 기록한다
현재 노드가 node이고, 다음 노드가 next_node일 때, 아직 방문하지 않았다면 parent[next_node] = node로 기록하면 됩니다.
탐색 흐름 시각화
DFS로 부모를 채우는 느낌
시작 : 1 → 6 방문 → parent[6] = 1 → 3 방문 → parent[3] = 6 → 5 방문 → parent[5] = 3
핵심은 “입력으로 부모를 받는 것”이 아니라, 탐색하면서 처음 방문하게 만든 현재 노드를 부모로 기록하는 것입니다.
최종 코드
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.readline
n = int(input())
graph = [[] for _ in range(n + 1)]
parent = [0] * (n + 1)
visited = [False] * (n + 1)
for _ in range(n - 1):
node1, node2 = map(int, input().split())
graph[node1].append(node2)
graph[node2].append(node1)
def dfs(node):
visited[node] = True
for next_node in graph[node]:
if not visited[next_node]:
parent[next_node] = node
dfs(next_node)
dfs(1)
for i in range(2, n + 1):
print(parent[i])
코드 한 줄씩 설명
왜 처음 시도는 틀렸을까?
잘못된 생각
parent[node1] = node2
이 방식은 입력 줄을 보는 순간 바로 부모를 확정해버립니다. 하지만 문제의 입력은 연결 정보일 뿐이므로, 어떤 쪽이 부모인지 아직 모르는 상태입니다.
반례 감각
예를 들어 입력에 4 1이 있다고 해서 바로 parent[4] = 1만 생각하는 건 위험합니다.
부모 관계는 반드시 1을 루트로 잡고 전체 연결을 따라가 본 뒤 결정해야 합니다.
실전 팁
1. 재귀 DFS는 런타임 에러가 날 수 있다
노드 수가 100,000개까지 가능하므로, 트리가 한쪽으로 길게 늘어지면 재귀 깊이도 매우 깊어집니다. 이때 sys.setrecursionlimit(10**6)이 없으면 재귀 깊이 초과가 날 수 있습니다. [Source](https://www.acmicpc.net/problem/11725)
2. 입력 속도 최적화가 체감된다
이 문제는 간선 입력이 많기 때문에 input = sys.stdin.readline을 사용하면 실행 시간이 꽤 줄어듭니다.
3. BFS로도 풀 수 있다
부모를 기록하는 핵심 로직은 같습니다. 탐색 방식만 DFS 대신 BFS로 바꿔도 정답이 됩니다.
마무리 정리
이 문제의 핵심 한 문장
입력의 간선은 부모 정보가 아니라 연결 정보이므로, 1번을 루트로 잡고 DFS/BFS를 하면서 처음 방문한 노드의 부모를 기록해야 합니다.
문제는 루트 없는 트리가 주어졌을 때, 1번을 루트로 정한 뒤 각 노드의 부모를 찾는 것입니다. 따라서 입력을 바로 부모 배열에 넣는 것이 아니라, 먼저 그래프로 저장한 뒤 탐색하면서 부모를 채워야 합니다.
'크래프톤 정글 > 정글에서 문제풀기' 카테고리의 다른 글
| [정글 알고리즘] - [중]-백준 11724 연결 요소의 개수 풀이 실버2 (4) | 2026.03.21 |
|---|---|
| [정글 알고리즘] - [중]-백준 1260 DFS와 BFS 풀이 실버2 (0) | 2026.03.21 |
| [정글 알고리즘] - [중] -백준 2294 동전 2- 골드 5 (1) | 2026.03.21 |
| [정글 알고리즘] - [중] -백준 2178 미로 탐색 실버1 (0) | 2026.03.21 |
| [정글 알고리즘] - [중] -백준 1707 - 이분 그래프-골드4 (1) | 2026.03.20 |