728x90
이 문제는 트리로 나타낼 수 있는 친구 관계에서 모든 개인이 새로운 아이디어를 수용하기 위한 최소 얼리 어답터의 수를 구하는 문제로, 얼리 어답터가 아닌 사람이 새로운 아이디어를 수용하기 위해서는 그 사람과 인접한 사람들이 모두 얼리 어답터여야 한다.
이 문제는 이전의 트리의 독립집합 문제와 유사한 방법으로 해결할 수 있다. 다만, 각 노드마다 자신이 얼리 어답터가 되는 경우와 그렇지 않은 경우로 나눠서 dynamic programming을 적용한다. 각 노드 u마다 자신이 얼리 어답터가 되는 경우 u를 루트로 하는 서브트리에서 u의 각 자식 노드가 얼리 어답터가 되든 안 되든 상관없으므로 두 경우 중 최소가 되는 얼리 어답터의 수를 u의 얼리 어답터의 수에 더한다. u가 얼리 어답터가 아닌 경우 u와 인접한 모든 노드들이 얼리 어답터여야 하므로 u의 각 자식 노드가 얼리 어답터가 될 때 최소가 되는 얼리 어답터 수를 u의 얼리 어답터의 수에 더한다.
base case인 leaf 노드의 경우에는 자신이 얼리 어답터가 되는 경우와 그렇지 않은 경우는 각각 얼리 어답터의 수가 1, 0이 될 것이다.
이를 코드로 구현하면 다음과 같다.
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**6)
n = int(input())
graph = [[] for _ in range(n+1)]
for _ in range(n-1):
u, v = map(int, input().split())
graph[u].append(v)
graph[v].append(u)
visited = [False for _ in range(n+1)]
# 최소가 되는 얼리 어답터의 수를 두 가지 경우로 나눠 저장한다.
# 앞의 수는 자신이 얼리 어답터가 되는 경우, 뒤의 수는 자신이 얼리 어답터가 아닌 경우이다.
dp = [[1, 0] for i in range(n+1)]
def DFS(currNode):
visited[currNode] = True
for v in graph[currNode]:
if not visited[v]:
DFS(v)
dp[currNode][0] += min(dp[v][1], dp[v][0])
dp[currNode][1] += dp[v][0]
DFS(1)
print(min(dp[1][0], dp[1][1]))
728x90
'알고리즘 문제' 카테고리의 다른 글
백준 2252번 : 줄 세우기 in Python (0) | 2021.06.04 |
---|---|
백준 1949번 : 우수 마을 in Python (0) | 2021.06.03 |
백준 2213번 : 트리의 독립집합 in Python (0) | 2021.06.03 |
백준 15681번 : 트리와 쿼리 in Python (0) | 2021.05.30 |
백준 17472번 : 다리 만들기 2 in Python (0) | 2021.05.29 |