BOJ 12704 Cheating a Boolean Tree (Large)

BOJ 12704 Cheating a Boolean Tree (Large)

문제 링크:

문제 내용

MM개의 노드로 이루어진 논리 회로가 주어집니다. 이 논리 회로는 이진 트리 모양으로, 1부터 MM까지 각 노드에 번호를 매겼을 때 M12\frac{M-1}{2}번 이하의 노드는 논리 게이트이고, 나머지 노드는 입력 노드입니다. xx번 논리 게이트는 2x2x번과 2x+12x+1번 노드를 입력으로 받습니다.

각 게이트는 AND 또는 OR 게이트입니다. 당신은 이 논리 회로에서 몇 개의 게이트를 골라 AND를 OR로, 또는 OR를 AND로 바꿀 수 있습니다.

이때, 최종 출력값이 VV가 되도록 하기 위해 바꿔야 하는 게이트의 최소 개수를 구하세요. 이미 최종 출력값이 VV라면 답은 0입니다.

입력

첫 번째 줄에 테스트 케이스의 개수 NN이 주어집니다. (2N202 \le N \le 20)

각 테스트 케이스에 대해, 첫 줄에 MMVV가 주어집니다. (3M99993 \le M \le 9999, 0V10 \le V \le 1)

다음 M12\frac{M-1}{2}개의 줄에 걸쳐서, 1번부터 M12\frac{M-1}{2}번 노드의 정보가 GGCC의 두 값으로 주어집니다. (0G,C10 \le G, C \le 1) GG가 1이면 AND, 0이면 OR 게이트이고, CC가 1이면 이 게이트를 바꿀 수 있음, 0이면 바꿀 수 없음을 의미합니다.

다음 M+12\frac{M+1}{2}개의 줄에 걸쳐서, M+12\frac{M+1}{2}번 노드부터 MM번 노드까지의 입력 노드의 값이 주어집니다.

출력

각 테스트 케이스에 대해, Case #{테스트 케이스 번호}: {문제의 정답}의 형식으로 출력합니다. 게이트를 어떻게 바꾸더라도 출력값을 VV로 만들 수 없다면 문제의 정답 대신 IMPOSSIBLE을 출력합니다.

문제 풀이

스포일러

이 문제는 트리 DP로 풀 수 있습니다.

각 서브트리에 대해, 현재 서브트리를 0이나 1로 만들고자 할 때 바꿔야 하는 게이트의 최소 개수를 계산할 수 있습니다. 아예 만들 수 없는 경우는 inf로 둡니다. 그러면, 양쪽의 자식 서브트리의 DP값을 보고 현재 서브트리의 DP값을 다음과 같이 계산할 수 있습니다.

  • 현재 게이트가 AND인 경우: 1로 만드는 비용 = 왼쪽을 1로 만드는 비용 + 오른쪽을 1로 만드는 비용, 0으로 만드는 비용 = min(왼쪽 0 + 오른쪽 0, 왼쪽 0 + 오른쪽 1, 왼쪽 1 + 오른쪽 0)
  • OR인 경우도 비슷하게 계산합니다.
  • 현재 게이트를 바꿀 수 있다면, 게이트가 반대일 때의 비용을 계산한 뒤 1을 더한 것과 각각 min을 취합니다.
Last updated on