Programming/백준
[골드 5] 백준 15681 - 트리와 쿼리 (파이썬)
pental
2025. 4. 28. 15:13
https://www.acmicpc.net/problem/15681
풀이
- 루트가 R인 트리가 주어짐
- 각 쿼리는 정점 U를 루트로 하는 서브트리의 정점 개수를 묻는다
- 여러 쿼리에 대해 빠르게 답변해야 하므로 DFS를 활용한 서브트리 크기 미리 계산이 핵심
adj = [[] for _ in range(N)]
adj[u]에 연결된 정점들 v를 저장하여 무방향 트리를 구성한다.
D = [0] * N
D[u]는 u를 루트로 하는 서브트리의 정점 수를 나타낸다.
def dfs(u):
visit[u] = True
D[u] = 1 # 자기 자신 포함
for v in adj[u]:
if not visit[v]:
dfs(v)
D[u] += D[v]
DFS를 통한 서브트리 크기를 계산하며, 재귀적으로 자식 노드의 서브트리 크기를 더해준다.
한번의 DFS로 모든 정점의 서브트리 크기 계산이 가능하다.
for _ in range(Q):
u = int(input())
u -= 1
print(D[u])
이미 계산해둔 D[u] 값을 출력하면 되므로 O(1) 시간을 가진다.
코드
# 백준 15681 - 트리와 쿼리
# 분류 : 다이나믹 프로그래밍
import sys
sys.setrecursionlimit(100000000)
input = sys.stdin.readline
N, R, Q = map(int, input().split())
R -= 1
adj = [[] for _ in range(N)]
for _ in range(N - 1) :
u, v = map(int, input().split())
u -= 1
v -= 1
adj[u].append(v)
adj[v].append(u)
visit = [False] * N
D = [0] * N
def dfs(u) :
visit[u] = True
D[u] = 1
for v in adj[u] :
if not visit[v] :
dfs(v)
D[u] += D[v]
dfs(R)
for _ in range(Q) :
u = int(input())
u -= 1
print(D[u])