私はチューン(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)。 }