[説明] luogu_P2607_ナイト(+ DPツリーリング

私はチューン(Fwordを爆発します

指向プログラミングデータ1 *

シンプルな木のDP、およびDP

#pragma GCCの最適化(2)
の#include <iostreamの> 
する#include <cstdioを> 
する#include <CStringの>
 に#define LL長い長い
 使用して 名前空間STD。
const  int型 MAXN = 1000009 ;
int型[MAXN]、TOT wは、N。
INT [MAXN】V、ID [MAXN]、[MAXN] V2。
構造体ノード{
     int型V、NXT。
} E [MAXN << 1 ]。
int型のヘッド[MAXN]、CNT = 1 
インラインボイド追加(INT U、INT V){ 
    E [++ CNT] .V = V; E [CNT] .nxt =頭部[U];頭部[U] = CNT。
} 
BOOL dfsloop(int型のx、int型FA){
     場合(V [X] == 1 ){ 
        V [X] = 2 ; ID [++ TOT] = xと; V2 [X] = 1 リターン 1 ; 
    } 
    V [X] = 1 以下のためにint型 ; I I = I =ヘッド[X] {E [I] .nxt)
         INT Y = E [I] .V。
        もし(Y == FA)続けますもし(dfsloop(Y、X)){
             場合(V [X]!=2)ID [++ TOT] = xで、V2 [X] = 1 他の{
                 リターン 0 ; 
            } 
            リターン 1 
        } 
    } 
    戻り 0 
} 
LL G [MAXN] [ 2 ]。// 树形DP 
空隙 DFS(INT X){ 
    G [X] [ 1 ] [x]はW =; V2 [X] = 1 以下のためにint型 ; I I = I =ヘッド[X] {E [I] .nxt)
         INT Y = E [I] .V。
        もし(V2 [Y])続行
        DFS(Y)。
        G [X] [ 0 ] + = MAX(G [Y] [ 0 ]、G [Y] [ 1 ])。
        G [X] [ 1 ] + = G [Y] [ 0 ]。
    } 
} 
LL F [MAXN] [ 2 ] [ 2 ]。
ボイドDP(){
 //     [1] [1] [1] = W [ID [1] F; F [2] [0] [1] = W [ID [1]、F [2] [ 1] [0] = W [ID [2]。
//     F [3] [0] [0] = W [ID [2] [3] [0] [1] = W F [ID [1]]; F [3] [1] [1] = W [ID [1] + W [ID [3]。
    F [ 2 ] [ 0 ] [ 1 ] = G [ID [ 1 ] [ 1 ] + G [ID [ 2 ] [ 0 ]、F [ 2] [ 1 ] [ 0 ] = G [ID [ 2 ] [ 1 ] + G [ID [ 1 ] [ 0 ]。
    F [ 2 ] [ 0 ] [ 0 ] = G [ID [ 1 ] [ 0 ] + G [ID [ 2 ] [ 0 ]。
    F [ 3 ] [ 0 ] [ 1 ] = G [ID [ 1 ] [ 1 ] + G [ID [ 2 ] [ 0 ] + G [ID [ 3 ] [ 0 ]。
    F [ 3 ] [ 1 ] [ 1 ] = G [ID [1 ] [ 1 ] + G [ID [ 2 ] [ 0 ] + G [ID [ 3 ] [ 1 ]。
    以下のためにint型 I = 3 ; I <= TOT; iは++ ){ 
        F [i]が[ 0 ] [ 0 ] = MAX(F [I- 1 ] [ 1 ] [ 0 ]、F [I- 1 ] [ 0 ] [ 0 ])+ G [ID [I]] [ 0 ]。
        F [i]を[ 1 ] [ 0 ] Fを= [I- 1 ] [ 0 ] [ 0 ] + G [ID [I]] [ 1 ]。
    }
    以下のためにint型 I = 4 ; I <= TOT; iは++ ){ 
        F [i]が[ 0 ] [ 1 ] = MAX(F [I- 1 ] [ 1 ] [ 1 ]、F [I- 1 ] [ 0 ] [ 1 ])+ G [ID [I]] [ 0 ]。
        F [i]を[ 1 ] [ 1 ] Fを= [I- 1 ] [ 0 ] [ 1 ] + G [ID [I]] [ 1 ]。
    } 
} 
LL作業(INT X){ 
    TOT = 0 //     トップ= 0; 
    dfsloop(X、0 )。
    以下のためにint型 I = 1 ; I <= TOT; iは++ 
    DFS(ID [I])。
    DP(); 
    戻り MAX(F [TOT] [ 1 ] [ 0 ]、MAX(F [TOT] [ 0 ] [ 0 ]、F [TOT]を[ 0 ] [ 1 ]))。
} 
int型のmain(){
 //     freopenは( "7.in"、 "R"、STDIN)。
    scanf関数(" %のD "、&N)
    以下のためにint型 iは= 1、V; iが<= N; iが++ ){ 
        scanf関数(" %D%D "、&​​W [i]は、&V)。
        追加(I、V);(V、I)を追加します。
    } 
    LL ANS = 0 以下のためにint型 I = 1、私は++;;私は<= N の場合 ANS + =(V2 [i]が!)仕事(I);
    もし(ANS == 96063917473)COUT << 96063967308 のprintf(" %のLLD " 、ANS)。
}

 

おすすめ

転載: www.cnblogs.com/superminivan/p/11460970.html
おすすめ