목차

Tree With One Edge

ps
링크acmicpc.net/…
출처BOJ
문제 번호32744
문제명Tree With One Edge
레벨플래티넘 4
분류

게임 이론

시간복잡도O(Σn)
인풋사이즈Σn<=2*10^5
사용한 언어Python 3.13
제출기록81744KB / 472ms
최고기록472ms
해결날짜2025/10/02

풀이

코드

"""Solution code for "BOJ 32744. Tree With One Edge".

- Problem link: https://www.acmicpc.net/problem/32744
- Solution link: http://www.teferi.net/ps/problems/boj/32744

Tags: [game theory]
"""

import sys
from teflib import psutils
from teflib import tree as ttree

ROOT = 0


def solve_dp(dp_children, _):
    loss_pos_count = sum(1 for is_win_pos, _ in dp_children if not is_win_pos)
    if loss_pos_count > 0:
        is_win_pos_cur = True
        if loss_pos_count > 1:
            change_pos_count = 0
        else:
            change_pos_count = next(
                count for is_win_pos, count in dp_children if not is_win_pos
            )
    else:
        is_win_pos_cur = False
        change_pos_count = sum(count for _, count in dp_children) + 1
    return (is_win_pos_cur, change_pos_count)


@psutils.run_n_times
def main():
    n = int(sys.stdin.readline())  # pylint: disable=unused-variable
    parents = [0] + [int(x) - 1 for x in sys.stdin.readline().split()]

    dp = ttree.dp_on_rooted_tree(ttree.RootedTree(ROOT, parents), solve_dp)
    loss_node_count = sum(1 for is_win_pos, _ in dp if not is_win_pos)
    is_win_pos, change_pos_count = dp[ROOT]
    change_edge_count = change_pos_count * loss_node_count
    if is_win_pos:
        print(n * n - change_edge_count)
    else:
        print(change_edge_count)


if __name__ == '__main__':
    main()