BZOJ 3677:[Apio2014] LianzhuラインツリーDP

彼は分析の本質に落ちた....(も慎重にタイトルを読んで)

慎重にタイトルを読んだ後、我々は、赤色エッジは、通信ブロックとリーフノード(または2つのリーフノード)を接続することができることを見出しました。

次に、もし法的な状態であれば、すべてのエッジのルートである点は、青色息子として形成されている場合にのみ、[X] - > X-> FA [X]

そして、このためな性質のため、我々は木-DPことができます。

$ 1 $ルート、$ F [x]は$ $ X $表す$ X $の中点の青側は$ G、サブツリーのルートである場合に最大値である[X] $を作ることは、時間で最大値が中間点ではない表します。

次いで、ルートは、$ 1 $でない場合、方法ルートDPへの転送を変更することにより、それは次の最小値と共に最小記録/転送を必要とします。

#include <cstdioを>   
する#include <ストリング> 
の#include <CStringの> 
する#include <アルゴリズム>   
の#define N 200007 
の#define 1000000000 INF 
名前空間stdを使用。    
ボイドsetIO(文字列s)
{ 
    = S +の文字列"に"。
    = S +アウト文字列"アウト。"; 
    freopenは(in.c_str()、 "R"、標準入力)。
    // freopenは(out.c_str()、 "W"、STDOUT)。
} 
INTエッジ、N、ANS。  
INT F [N]、G [N]、HD [N]、[N << 1]、NEX [N << 1]、ヴァル[N << 1]、F1 [N]、F2 [N]。      
ボイド追加(INT U、V INT、INT C)
{ 
    NEX [++エッジ] = HD [U]、HD [U] =縁、[エッジ]へ= V、ヴァル[縁] = C。
} 
無効DFS(int型のuを、
    (; iはNEX [I] = [U] INT I = HD)用
    { 
        int型V =に[I]を、
        (V == FF)は継続であれば、   
        DFS(V、U); 
        G [U] + = MAX(G [V]、F [V] +ヴァル[I])。                    
    }     
    のための(INT I = HD [U]; iが、iはNEX [I] =)
    { 
        int型V =に[I]を、
        (V == FF)は継続であれば、         
        F [U] = MAX(F [U]、G [U] -max(G [V]、F [V] +ヴァル[I])+ G [V] +ヴァル[I])。   
        INT TMP = G [V] +ヴァル[I] -max(G [V]、F [V] +ヴァル[I])。    
        IF(TMP> F1 [U])F [U] = F1 [U]、F1 [U] = TMP。        
        そうであれば(TMP> F2 [U])F [U] = TMP。      
    } 
} 
ボイドDFS2(INT U、INT FF)
{   
    ANS = MAX(ANS、G [U])。   
    (; iはNEX [I] = [U] INT I = HD)用
    { 
        int型V =に[I]を、   
        (V == FF)は継続であれば、     
        GU INT = G [U] -max(G [V]、G [V] + F1 [V] +ヴァル[i])と、FU。    
        IF(F1 [U] == G [V] +ヴァル[I] -max(G [V]、G [V] + F1 [V] +ヴァル[I]))FU = F2 [U]。     
        他FU = F1 [U];   
        G [V] + = MAX(GU、GU + FU +ヴァル[I])。       
        FU = GU +ヴァル[I] -max(GU、GU + FU +ヴァル[I])。      
        IF(FU> F1 [V])F [V] = F1 [V]、F1 [V] = FU。   
        そうであれば(FU> F2 [V])F [V] = FU。
        DFS2(V、U);   
    } 
} 
int型のmain()
{ 
    // setIO( "入力")。  
    INT I、J、X、Y、Z。
    scanf関数( "%のD"、&N);  
    scanf関数( "%D%D%D"、およびX&Y、およびZ)、(X、Y、Z)を追加し、(X、Y、Z)を追加;(; I <N ++ iは= 1)のための   
    ANS = -inf。
    DFS(1,0)。   
    printf( "%dの\ n"は、ANS)。
    0を返します。
}

  

おすすめ

転載: www.cnblogs.com/guangheli/p/12131872.html