세트 $의 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 ; }