トピックリンクします。https://vjudge.net/problem/HDU-2196
問題の意味:木、到達可能な最大距離を求めて、各ノード与えられました。
アイデア:
ツリーがある場合は最長の距離は、ライン上の2つのBFSを得ています。しかし、ここではすべての時間のように、木のDP古典的なタイトルの最も遠い地点である、またはDPが少なすぎるをやって求めます。任意のノードuのために利用可能な分析は、最大距離のいずれかに延びる下方上方いずれかの最長の距離を延長最長の距離です。
我々は、[U]は[0]下向き最長距離の(サブノード)ノードUを表し、DP、Ptの[U]このような最長距離U-スルーとして、最長距離を介して第1の子ノードの数を記録> Vは、PT [U] = V。DP [U] [1]下向きUを記録する第二の最短距離、DP [U] [0]、DP [U] [1] 1つのDFS、サブノードによって得られたDFS情報親ノードによって得ることができます。
DP [U] [2]までの最長距離の記録ノードU(親ノード)、Uは親ノードをkとする二つのケースを考えます。
1.pt [K] = U(最長パスUを通って下方K):DP [U] [2] = W 区 + MAX(DP [K]、DP [K] [2] [1])、その親ノード時間が長い距離を移動するために、距離はまだアップしています。
2.pt [K] = U :! DP [U] [2] = W 区 + MAX(DP [K] [0]、DP [K] [2])親ノードを移動するための、すなわち、最長の距離、又は距離アップ。
各ノードについて、結果がMAX(DP [U] [0]、DP [U] [2])です。
ACコード:
書式#include <cstdioを> する#include <アルゴリズム> 書式#include <CStringの> 使用して 名前空間はstdを、 const int型 MAXN = 10005 ; 構造体ノード{ int型NEX、W、V、。 }エッジ[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 =ヘッド[U] {エッジ[I] .nex) のint V =エッジ[I] .V、W = エッジ[I] .W。 DFS1(V); もし(DP [V] [ 0 ]> = DP W + [U] [ 0 ]){ PT [U] = V。 DP [U] [ 1 ] DP [U] [= 0 ]。 DP [U] [ 0 ] DPを= [V] [ 0 ] + W。 } そう であれば(DP [V] [0 ] + DP [U] [> W 1 ]) DP [U] [ 1 ] DPを= [V] [ 0 ] + W。 } } ボイド DFS2(int型U)を{ ため(int型 I =ヘッド[U]; 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 ; iは= N <; ++ I){ int型、U、W。 scanf関数(" %dの%のD "、&U、&W)。 ADDE(U、I、W)。 } DFS1(1 )。 DFS2(1 )。 以下のための(int型 I = 1; iが<= N; ++ I) のprintf(" %Dを\ n "、MAX(DP [I] [ 0 ]、DP [I] [ 2 ]))。 } 戻り 0 。 }