白駿-優秀村(1949)



Tree + Dynamic Programming


質問する


Nの村からなる国があります.便利村には1からNの番号があると言ってください.この国は木の構造からなっている.つまり、N-1の道が村と村の間を直接結んでいて、どの道も方向性がなく、A番村からB番村まで行けば、B番村からA番村まで行けます.また、すべての村がつながっています.2つの村の間に直接つながる道がある場合、2つの村が隣接しているそうです.
この国の住民の達成感を高めるため、以下の3つの条件を満たす中で、N村の中からいくつかの村を「優秀な村」として選定しようとした.
1.'우수 마을'로 선정된 마을 주민 수의 총 합을 최대로 해야 한다.
2. 마을 사이의 충돌을 방지하기 위해서, 만일 두 마을이 인접해 있으면 두 마을을 모두 '우수 마을'로 선정할 수는 없다. 즉 '우수 마을'끼리는 서로 인접해 있을 수 없다.
3. 선정되지 못한 마을에 경각심을 불러일으키기 위해서, '우수 마을'로 선정되지 못한 마을은 적어도 하나의 '우수 마을'과는 인접해 있어야 한다.
各村の住民数と村間道路の情報が与えられた場合、与えられた条件を満たすために「優秀村」を選択するプログラムを作成してください.

入力


最初の行は整数Nを与える.(1≦N≦10000)2行目には、村の住民数を示す自然数がN個あり、スペースを隔てている.1番村からN番村まで順次与えられ、住民数は10000以下である.3行目からN-1行目まで、隣接する2つの村の番号はスペースを隔てています.

しゅつりょく


1行目は「優秀村」住民数の合計を出力する.
import sys
sys.setrecursionlimit(10**9)
 
n = int(sys.stdin.readline())
nodeValue=[0] + list(map(int,sys.stdin.readline().split()))
Tree = [[] for _ in range(n + 1)]
DP = [[0,0] for _ in range(n + 1)]
 
for _ in range(n-1):
    a,b=map(int,sys.stdin.readline().split())
    Tree[a].append(b)
    Tree[b].append(a)
 
check=[False for _ in range(n+1)]

def DFS(current):
    check[current] = True
    DP[current][0] = nodeValue[current]
    DP[current][1] = 0
    for i in Tree[current]:
        if not check[i]:
            DFS(i)
            DP[current][0] += DP[i][1]
            DP[current][1] += max(DP[i][0],DP[i][1])
 
DFS(1)
print(max(DP[1][0], DP[1][1]))
最低価格でGRADYのように購入する問題
参照)
https://developmentdiary.tistory.com/454