Codeforces 1249 F. 최대 무게 부분 집합

세트 $의 F는 [X] [I]는 $ 최근 $ i 서 $ 합법적 인 방식에서 최대 값으로 선택된 노드의 $ X를 $에서 $ X $으로 서브 트리를 나타낸다

$ 브로는 [X] $을 $ X를 $으로 노드의 값을 나타내고, 다만, 먼저 $ f를 [X] [0] = 브로 [X] $이고

이어서 $ f를 [X] [분 (I, J + 1)] = 최대 ([X] F [분 (I, J + 1)], F [X] [I]를 + F와 서브 트리를 함께 고려 [V] [J]) $

[X] [I]가 $가 $ V $ 기여를 포함하지 않는 현재의 $의 F에서 것을 유의 이것은 새로운 $ f를 [X] $에서 앞으로 $ tmp를 $ 입금 넣고, 마지막으로 덮어 통일 수도

해답은 다음 [RT] 내부 상태는 $ 최대 취할 F $이고

복잡성 $의 N ^ 3 $

사용법 #include <iostream> 
#INCLUDE <cstdio> 
#INCLUDE <알고리즘> 
#INCLUDE <CString을> 
#INCLUDE <cmath> 
#INCLUDE <벡터>
 사용  스페이스 성병;
타입 정의  LL;
인라인 INT의 읽기 ()
{
    INT (X) = 0 , F = 1 ;  CH = getchar가 ();
    동안 (CH2 < ' 0 ' || CH> ' 9 ' ) { 경우 (CH2 == ' - ' ) F = - 1 ; CH = getchar가 (); }
     동안 (CH2> = ' 0 ' && CH <=에서 ' 9 ' ) {(X) = (X << 1 ) + (X << 3 ) + (CH는 ^ 48 ); CH = getchar가 (); }
     리턴 의 X *의 F 단계;
}
CONST의  INT의 N = 207 ;
INT의 N, m, 발 [N];
INT 전나무 [N] 으로부터 [N << 1 ], [N에 << 1 ] cntt;
인라인 공극 담기 ( int로 A, INT의 {B)의  을위한 [CNTT ++] = [A]; [및] = CNTT 용; [CNTT = 행의 B; }
 Int 수 F [N] [N], TMP [N], ANS;
벡터 < INT > 아들 [N];
보이드 DFS ( INT (X), INT FA)
{
    F [X] [ 0 ] = 브로 [X];
    위한 ( int로 I = 전나무 [X] I, I = 로부터 [I])
    {
        INT 및 V = 내지 [I]; 경우 (V == FA가) 계속 ;
        DFS (V, X); memset 함수 (TMP, 0 , 는 sizeof (TMP));
         ( INT의 J = 0 ; J <= N; J ++ )
              ( INT K = 0 ; K <= N; ++ 케이 )
                 경우 (J + K + 1 > m) TMP [분 (j, K + 1 ) = 최대 ( TMP [분 (j, K + 1 )], F [X] [J] + F [V] [K]);
         ( INT의 J = 0 ; J <= N; J ++) [X]가 [j]가 F = TMP [J]을;
    }
}
int 형 ) (주
{
    N =) (읽기, m =) (판독; int로 A, B 단계;
    위한 ( int로 I = 1 발은 [I] =; I ++는, 난 <= N) ) (판독;
    경우 (N 개의 == 1 ) {의 printf ( " % D \ 없음 " , 발 [ 1 ]); 반환  0 ; }
     에 대해 ( int로 I = 1 ; i가 N <; 내가 ++ )= 판독 (), B = 읽기 ()
        (a, b), 추가 (b, a);
    DFS ( 1 , 0 );
    위한 ( int로 I = 0 ANS = 최대 (ANS, F [내가 ++; N = 난 <) (1) [I]);
    의 printf ( " % D \ 없음 " , ANS);
    반환  0 ;
}

 

추천

출처www.cnblogs.com/LLTYYC/p/11756634.html