728x90
난이도 : 골드4
풀이일 : 2403052
https://www.acmicpc.net/problem/3584
3584번: 가장 가까운 공통 조상
루트가 있는 트리(rooted tree)가 주어지고, 그 트리 상의 두 정점이 주어질 때 그들의 가장 가까운 공통 조상(Nearest Common Anscestor)은 다음과 같이 정의됩니다. 두 노드의 가장 가까운 공통 조상은, 두
www.acmicpc.net
링크로 이동하기 귀찮은 분들을 위한 문제 캡쳐
1차 시도 오답
import sys
from collections import deque
def sol(n, m):
# n의 자식들의 자식들을 찾아나가며 m 찾기
queue = deque([n])
while queue:
x = queue.popleft()
for y in tree[x]:
# m 발견 시 return
if y == m:
return print(n)
queue.append(y)
# n 대신 n 부모 노드로 재귀 호출
if parent[n]:
sol(parent[n], m)
T = int(sys.stdin.readline())
for _ in range(T):
N = int(sys.stdin.readline())
# 자식 정보, 부모 정보 저장
tree = [[] for _ in range(N + 1)]
parent = [0] * (N + 1)
for _ in range(N - 1):
A, B = list(map(int, sys.stdin.readline().split()))
tree[A].append(B)
parent[B] = A
a, b = list(map(int, sys.stdin.readline().split()))
sol(a, b)
틀린 이유
- m이 n의 부모일 경우를 고려하지 못함
반례
입력 | 1 2 1 2 2 1 |
출력 | 1 |
정답 코드
import sys
from collections import deque
def sol(n, m):
# m이 n의 부모라면 m 출력
if parent[n] == m:
return print(m)
# n의 자식들의 자식들을 찾아나가며 m 찾기
queue = deque([n])
while queue:
x = queue.popleft()
for y in tree[x]:
# m 발견 시 return
if y == m:
return print(n)
queue.append(y)
# n 대신 n 부모 노드로 재귀 호출
sol(parent[n], m)
T = int(sys.stdin.readline())
for _ in range(T):
N = int(sys.stdin.readline())
# 자식 정보, 부모 정보 저장
tree = [[] for _ in range(N + 1)]
parent = [0] * (N + 1)
for _ in range(N - 1):
A, B = list(map(int, sys.stdin.readline().split()))
tree[A].append(B)
parent[B] = A
a, b = list(map(int, sys.stdin.readline().split()))
sol(a, b)
코드 변화
- sol 함수에 m이 n의 부모이면, 출력하게 하는 부분 추가
- 재귀 호출 시, 루트 노드인지 확인하던 조건 제거
코드 구성
- sol 함수
- m이 n의 부모라면, m 반환 후 종료
- deque에 n을 넣고, n의 모든 자식들의 자식들을 탐색
- 만약, 자식을 탐색 중 m을 발견하면 n 반환 후 종료
- n 대신 parent[n]을 넣어 함수 재귀 호출
- tree : 각 노드가 자식으로 갖는 노드들을 기록하기 위한 이차원 배열
- parent : 각 노드의 부모를 기록하기 위한 배열
- 0 번째 인덱스를 제외하고, parent[n]이 0이라면 루트노드
- 입력 받는 동안 tree, parent를 기록
- 가장 가까운 공통 조상을 구해야 하는 두 수에 대해 sol 실행
느낀점
- deque 문제를 주구장창 풀었던 때 때문인지 재밌게 풀었다. 틀렸을 땐 안재밌었지만.
- 반례를 찾아보지 말고 스스로 생각해보는 습관을 길러야 하는데 자꾸 반례부터 찾아보게 되어서 문제다.
- 제출 시간은 00:00:08로 찍혔지만, 어쨌건 나는 5일 문제로 분류해야지 그래도 안 풀려다가 한 문제 푸니까 되게 뿌듯하네ㅎㅎ
'알고리즘 > 🥇 골드' 카테고리의 다른 글
백준 11437 LCA 파이썬 풀이 (0) | 2024.03.12 |
---|---|
백준 4803 트리 파이썬 풀이 (0) | 2024.03.08 |
백준 5639 이진 검색 트리 파이썬 풀이 (0) | 2024.03.04 |
백준 7662 이중 우선순위 큐 파이썬 풀이 (2) | 2024.02.28 |
백준 11780 플로이드 2 파이썬 풀이 (1) | 2024.02.11 |