hdoj2196 (트리 DP, 나무의 직경)

항목 링크 : 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 ; 
}

 

추천

출처www.cnblogs.com/FrankChen831X/p/11375572.html