항목 링크 : HTTPS : //vjudge.net/problem/HDU-2196
문제의 의미 : 나무 주어진 도달 할 수있는 최대 거리를 추구하는 각 노드.
아이디어 :
나무 인 경우 가장 긴 거리가, 라인에있는 두 개의 BFS를 얻을 수있다. 그러나 여기에 모든 시간과 같은 트리 DP 고전적인 제목의 가장 먼 지점, 또는 DP가 너무 작은 일을 추구합니다. 노드 U 가능한 분석은 최대 거리를 연장하거나, 승 하강 중 최장 거리를 연장하는 긴 거리이다.
우리는 [U]를 [0] 하향으로 긴 거리 (하위 노드) 노드 U를 나타내고, DP, 편 [U 이러한 긴 거리 U- 내지 같이 긴 거리를 통해 제 자식 노드의 수를 기록 > V 후 PT [U] = V. DP [u는 [1]는 u 하향 번째로 짧은 거리를 기록 DP [U] [0], DP [U] [1] DFS, 하위 노드에 의해 얻어진 DFS 정보 부모 노드에 의해 수득 될 수있다.
DP는 [U]는 긴 거리의 [2]가 기록 U 노드 (상위 노드), U, 두 케이스를 고려 부모 노드는 K라고 가정한다 :
1.pt [K] = U (U 긴 경로를 통해 아래쪽으로 K) : DP [U] [2] = W 구 + 맥스 ([. 1] DP [K, DP [K] [2]), 그 부모 노드 시간이 긴 거리를 이동하는 거리가 여전히있다.
2.pt [K] = U :! DP [U] [2] = W 구 + 최대, 즉, 가장 긴 거리가 부모 노드를 이동하는 ([0], DP [K]가 [2] DP [K]), 또는 거리까지.
각 노드에 대해, 결과는 최대이다 (DP [U] [0], DP [U] [2]).
AC 코드 :
#INCLUDE <cstdio> #INCLUDE <알고리즘> #INCLUDE <CString을> 사용 스페이스 성병; CONST INT maxn = 10005 ; 구조체 노드 { INT의 V, NEX w; } 에지 [maxn]; INT의 N, DP [maxn] [ 3 ], PT [maxn, 헤드 [maxn, CNT; 보이드 adde ( int로 U, INT의 V, INT w) { 에지 [ ++ CNT] .V = V; 에지 [CNT] .W = w; 에지 [CNT] .nex = 헤드 [U]; 헤드 [U] = CNT; } 보이드 dfs1은 ( INT U) { DP는 [U]를 [ 0 ]을 DP = [u는 [ 1 ]을 PT = [U] = 0 ; 위한 ( int로 ; I I = I = 헤드 [유] {에지 [I]를 .nex) 의 INT V = 가장자리 [I] .V, w = 에지 [I] .W; dfs1 (V); 경우 (DP [V] [ 0 ]> = w + DP [U] [ 0 ]) { PT [U] = V; DP는 [u는 [ 1 ]을 DP = [U] [ 0 ]; DP는 [U]를 [ 0 ]을 DP = [V] [ 0 ] + w; } 다른 경우 (DP [V]0 > DP w] +는 [u는 [ 1 ]) (DP)가 [u는 [ 1 ]을 DP = [V] [ 0 ] + w; } } 공극 DFS2 ( INT U) { 위해 ( int로 난을 = 헤드 [유] I, I = 가장자리 [I]를 .nex) { INT의 V = 가장자리 [I] .V = w 에지 [I] .W; 경우 (PT는 [U]는 == V) DP는 [V] [ 2 ] + W 최대 = (DP [U] [ 1 ], DP [U] [ 2 ]); 다른 DP는 [V] [ 2 ] + W 최대 = (DP [U] [ 0 ], DP [U] [ 2 ]); DFS2 (V); } } INT주 () { 동안 (~는 scanf ( " %의 D ' , N)) { CNT = 0 ; memset 함수 (헤드, 0 , 는 sizeof (헤드)); 위한 ( int로 I = 2 ; 나는 <= N; ++ I) { int로 , U w; scanf와 ( " % d 개 %의 D ' , U, w); adde (U, I, w); } dfs1 ( 1 ); DFS2 ( 1 ); 대 ( INT I = 1; 나는 <= N; ++ I) 의 printf ( " % D \ 없음 " 맥스 (DP [I] [ 0 ], DP [I] [ 2 ])); } 반환 0 ; }