【ZJOI2007】時間同期ツリーDP

問題の意味:キーポイントから要求するように、ノードのN無根木与え、各エッジは重みVを有し、キーとしてポイントを選択し、あなたは、エッジの重みを任意に拡大することができ、距離の任意のリーフノードが同じと重量を増加する必要があります。

 

データ範囲:

以下のため4。0 データの%、N千≤

。1 0 0 データの%、N≤500000、1000000≤V

 -------------------------------------分割ライン----------- -------------------------

ソリューション:比較的明白な木DP、我々は最も長いチェーンに他のチェーンと同等のだと思うのが難しいです。

エッジ上方NUMの現在のノード番号、および現在のノードの端からリーフノードとの距離の和に、再びプロセスをツリーを走査します。

エナジャイザのMAXNからリーフノード遠いから計算[x]は、次いで、他のリーフノードのために、MAXNれる見かけ長さを大きくする必要が[X] * NUM - 和。

答えが蓄積することができます。

#include <ビット/ STDC ++ H> の#defineは長い長いっ
 の#define融点make_pair用
 の#define REPは(iは、、B)は、(i ++は; iが=(B)<I =(A)INT)のため
 の#defineを(パーI、B)(iは(A = INT)のために、I> =(B); i--)使用して名前空間STDを、
typedefのペア < int型int型 > PII。
typedefをダブルデシベル。
CONSTのINT N = 1E6 + 50 int型[N]、N、根; 
int型のヘッド[N]、CNT = 0 
LL MAXN [N]、F [N]。構造体ノード{にLL次、V。} E [N]。
インラインint型



 
 
read()は{
     int型のx = 0、F = 1 チャー CH = GETCHAR()。
    一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ')、F = - 1CH = GETCHAR();}
     一方(CH> = ' 0 ' && CH <= ' 9 '){X =(x << 3)+(X << 1)+(CH ^ 48)。CH = GETCHAR()。
    
}
ボイド追加(int型のx、int型の Y、int型Z){ 
    E [ ++ CNT] .TO = Y。E [CNT] .V = Z。
    E [CNT] .next =頭部[X]。ヘッド[X] = CNT。
} 
ボイドのinit(){ 
    N =)(読み取ります。ルート= リード()。
    担当者(I、1、N- 1 ){
         int型XX、YY、ZZ。
        XX =リード()。YY = read()は、ZZ = リード()。
        (XX、YY、ZZ)を追加します。
        (YY、XX、ZZ​​)を追加します。
    }   
} 
ボイド DFS(int型のx、int型FA){ 
    F [X] = 0、MAXN [X] = 0 ; 
    LL和 = 0、NUM = 0 以下のためにint型 ; I I = I =ヘッド[X] {E [I] .next)
         INT Y = E [I] .TO。
        もし(Y == FA)続けます
        DFS(Y、X)。NUM ++ ; 
        F [X] + = F [Y]。
        MAXN [X] = MAX(MAXN [Y] + E [I] .V、MAXN [X])。 + =(LL)MAXN [Y] + E [I] .V。
    } 
    F [X] + =(LL)MAXN [X] * NUM -和; 
} 
ボイドワーク(){ 
    DFS(ルート、0 ); 
    printf(" %LLDする\ n " 、F [ルート])。
} 
int型のmain(){ 
    INIT()。
    作業(); 
    リターン 0 ; 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/smilke/p/11576955.html