説明
右側が、ポイントANSを得るようにしながら所定の大ツリーノードは、右ビット最小コスト、請求$コスト= \和\ limits_ {i = 1} ^ {n}は{ヴァル[I] * DIS(ANS、I)} $
溶液
木のDP
それでも二回DFSを通じて解決
核となるアイデアは、(用語はLYDから来ている「アルゴリズムコンテストステップアップガイド」)「ルート法をスキャンし、変更する第二」であります
我々は、DFSルートであり、DISを犠牲にして配置されたとき、最初のパスは、ANSが決定されると仮定する
TOT [j]はjが表す$ DIS [I] = \和の\ limits_ {息子にj個の\(I)} {DIS [J] + LEN(I、J)* TOT [J]} $は、明らかに存在しますノード点をルートと右サブツリー、および
だから我々は、「チェンジ・ルート」を達成するために、再度DFS
現在のノードを仮定iと、私は父が正しく計算されていた、我々は[FA] $ F $のように父親に位置価格ANSを覚えて、我々は、$ F [FA] $で[i]は$ F $を見つける方法を検討します
$ F二つの部分からなる[FA] $:ルートにするサブツリーと、残りのI配慮を。[FA] Fだから我々は最初の$ $ iはマイナスサブツリーのルートのコスト、そして私は、私費を行ってきました、プラス私のの残りの費用が来ることをルートとするサブツリーを追加
詳細な実装コードを参照してください。
時間の複雑さは$ O(n)は$です
コード
1つの#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 typedefの長い 長いLL。 4 のconst int型 MAXN = 100010 。 5インラインint型リード(){ 6 INT RET = 0、OP = 1 。 7 チャー C = GETCHAR()。 8 ながら(!isdigit(c)参照){ 9 もし(C == ' - ')OP = - 1 。 10 のC =getchar関数(); 11 } 12 ながら(isdigit(C)){ 13 RET = RET * 10 + C - ' 0 ' 。 14 C = GETCHAR()。 15 } 16 リターンのRET *のOP。 17 } 18 構造体ノード{ 19 のint NXT、DIS、であり; 20 } [MAXN << 1 ]。 21 のint NUM、ヘッド[MAXN]、N、ヴァル[MAXN]。 22 LLのTOT [MAXN]、DIS [MAXN]、[MAXN] F。 23 LLの合計。 24インラインボイド追加(INT から、INTに、int型のDIS){ 25 [++ NUM] .nxt =先頭から]。 26 [NUM] = .TO に、 27 [NUM] .DISの=のDIS。 28 ヘッド【から】= NUM。 29 } 30 LL DFS(INT今、int型{FA)を 31 ため(登録をint ; iは= I =ヘッド[今] {[I] .nxt) 32 INT =に[I] .TOと、 33 であれば(FAを==ため)続け; 34 LLのRET = (現在の)DFS。 35の DIS [今] + = DIS + [へ] [I] .DIS * RET。 36の TOT [今] + = RET。 37 } 38 リターン TOTは、[今] TOT [今] + = ヴァル[今]。 39 } 40 空隙 DP(int型今、INT FA){ 41 用(登録をint i =ヘッドは[今];私は私は= {[I] .nxt) 42 INTを =に[I] .TO。 43 であれば(FAを==する)続けます。 44 ( - )TOT〔へ] [I] .DIS *(和)+ + - (+ [I] .DIS *)へ] TOT(DIS [に対する] F [今])F = [する] DIS [に]; 45 DP(今に)。 46 } 47 } 48 、INT (){主 49 N = (読み取り) 50 のために(登録をint i = 1のval [i]を読み出す=()、和+ = ++ I; iが<= N)のval [I]。 51 のために(登録をint i = 1 ; iがN <; ++ i)が{ 52 INTは X =読み取る()、yは読み取ら=()、Z =を読み取ります()。 53 追加(X、Y、Z)。(Y、X、Z)を追加します。 54 } 55の DFS(1、1 )。 56 F [ 1 ] = DIS [ 1 ]。 57 DP(1、1 )。 58 LL ANS = 9223372036854775806ll。 59 のために(登録をint i = 1 ; iは= N <; ++ I)ANS = 分(ANS、F [I])。 60 のprintf(" %LLDする\ n " 、ANS)。 61 リターン 0 。 62 }