説明
木を考えると、ポイントを見つける最も遠い距離に到達するためには、それぞれ数です
溶液
木のDP
私たちは、最初のノードがルートであることを前提とし、「第2のスキャンと変更ルートの法則」のアイデアを使用し、その後、一度離れてと倍のサブツリー遠い内の各ノードから取得したDPツリーでツリーのルートがありますSUM1で示される距離、SUM2
我々は、[i]は、ツリー内の電流Iから出発して、ルート付きツリーの場合を示しANSを定義する、非最大距離までそのサブツリーノードは、答えは$最大\ {ANSどのくらい、この時点で[I] 、SUM1 [I] \} $
その後、我々は「変更ルート」を考えます
現在のノードの父のANSが正しく計算されたと仮定し、その後、現在のノードのために、非常に少ない場合があります。
- 父親の現在のノードのないSUM1、その後、現在のノードの最大値は、現在のノードの父から、その父親と父親の父親からのANS + ANS + SUM1現在のノードであり、
- 父親のSUM1現在のノードの後、現在のノードのANSは父と父ANS +父を持つノードから現在の最大距離とその父親のSUM2 +現在のノードの距離であります
私たちは、DPを完了するために、二回、この木のDFS
時間の複雑さは$ O(n)は$です
コード
1つの#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 CONST INT MAXN = 10010 。 4 INT N。 5 構造体ノード{ 6 int型NXTに、DIS。 7 } [MAXN << 1 ]。 8 int型ヘッド[MAXN]、NUM。 9インラインボイド追加(INT から、INTに、int型のDIS){ 10 [++ NUM] .nxt =先頭から]。 11 [NUM] .TO =に; 12 [NUM] .DISの=のDIS。 13 ヘッド【から】= NUM。 14 } 15 のint SUM1 [MAXN]、SUM2は[MAXN]は、[MAXN] ANS。 16 INT DFS(INT今、int型{FA)を 17 ため(登録をint ; iは= I =ヘッド[今] {[I] .nxt) 18 INT =に[I] .TOと、 19 であれば(FAを==する)続けます。 20 SUM2 [今] = MAX(SUM2 [今]、DFS(今まで)+ [I] .DIS)。 21 であれば(SUM2 [今]>SUM1 [今])スワップ(SUM2 [今]、SUM1 [今])。 22 } 23 リターンSUM1 [今]。 24 } 25 空隙 DP(int型今、INT FA){ 26 用(登録をint i =ヘッドは[今];私は私は= {[I] .nxt) 27 INTを =に[I] .TO。 28 もし(FAを==に)続けます。 29 であれば(SUM1 [に対する] + [I] .DIS == SUM1 [今]){ 30の 、最大= [に対して] ANS([今] SUM2 + [I] .DIS、[I] .DIS + ANS [今])。 31 } 32 他{ 33の [へ] ANS = MAX([今] SUM1 + [I] .DIS、[I] .DIS + ANS [今])。 34 } 35 DP(今に)。 36 } 37 } 38 INT メイン(){ 39 ながら(〜のscanf(" %d個"、&N)){ 40 NUM = 0 。 41 のmemset(ヘッド、0、はsizeof (ヘッド))。 42 のために(登録をint i = 2 ; iが<= N ++ {I) 43 INTX、V。 44 のscanf(" %D%dの"、およびX、およびV)。 45 追加(I、X、V)。追加(X、I、V); 46 } 47 のmemset(SUM1、0、はsizeof (SUM1))。 48 のmemset(SUM2、0、はsizeof (SUM2))。 49 のmemset(ANS、0、はsizeof (ANS))。 50の DFS(1、1 )。 51 DP(1、1 )。 52 のための(登録をint i = 1 ; iは= N <; ++ I) 53 のprintf(" %Dを\ n " 、MAX(ANS [i]は、SUM1 [I]))。 54 } 55 リターン 0 。 56 }