codeforces1156D 0-1ツリールートの変更DP

トピックポータル

質問の意味:

  ツリーのn点のエッジの重みは0または1で与えられ、有効なパス(x、y)は(Y≠をx)が満たされ、X yから移動し、一旦エッジの右側を通って、そうではありません次いで0側に右側を通って、条件を満たすエッジの数を見つけますか?

思考:セットの$ F [U] $ 1のルートであり、ボトムエンドノード$ U $は有効パス1の数は、$ G [U]ルートの$ 1代表、ボトムアップであります$のV $エンド・ノードが正当なパス0の数であり、これは再び単純DFSによって解決することができます。

  次に、設定$ NF [U] $と$ NG [u]がuはルート・パス、整流DFSルート、プロセスのルート変更である法的$の2種類の数を表します。

  一方の側の縁は、その後、0の場合:

    $呉[st.to] = NG [U] $、$ NF [st.to] = [st.to] F $。この式はまた、よく理解され、パスの白側が変更されない、パスが不正である場合にエッジ上に上から下に、親ノードから転送されたすべての黒。

  図1は、次いで、側縁である場合:

    $ン[st.to] = G [st.to] $、$ NF [st.to] = NF [U] -g [st.to] + ngの[U] $は、白エッジは、底部から出てきますの。ブラックにより形成された側縁部と、親ノードプラス白側を接続して形成されたエッジの親ノード黒と白側の現在位置側に黒側を差し引きます。

#pragma GCCの最適化(2)
 の#pragma G ++最適化(2)
 の#pragmaコメント(リンカー、 "/ STACK:102400000,102400000")
の#include <ビット/ STDC ++ H> 
の#include <cstdioを> 
する#include <ベクトル>
 の#define担当者(iは、、B)のための(iは= int型、iが<= bは、iが++)
 の#define DEP(I、B、A)(iはBを= int型;方には> =; i--)
 の#define CLR(B)のmemset(A、B、はsizeof(A))
 の#define PB一back
 の#define PII対<整数、整数>
 使用して 名前空間STDを、
typedefの長い 長いLL。
const  int型 MAXN = 200010 ; 
LL用RD()
{ 
    LL X = 0、F = 1チャー CH = GETCHAR()。
    一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ')、F = - 1 ; CH = GETCHAR();}
     一方(CH> = ' 0 ' && CH <= ' 9 '){X = X * 10 + CH- ' 0 ' ; CH = GETCHAR();}
     戻りのx *のF。
} 
int型のT。
構造体の縁{
     INT W、であり; 
}。
ベクター <エッジ> VEの[MAXN]。
INT F [MAXN]、G [MAXN]、NF [MAXN] ngの[MAXN]。
INTのN、M。
ANS LL; 
ボイド dfs_1(int型 U、int型のFA){
     ための(自動&ST:VEの[U]){
         場合(st.to == FA)続けます
        dfs_1(st.to、U)。
        もし(st.w == 0 ){ 
            G [U] + = G [st.to] + 1 
        } { 
            [U] F [st.to] + + = F 1 +G [st.to]。
        } 
    } 
} 
ボイド dfs_2(INT U、INT FA){ 
    ANS + = NF [U] + [U]をngの。
    (オート&ST:VEの[U]){
         場合(st.to == FA)続けますもし(st.w == 0 ){ 
            NG [st.to] = NG [U]。
            NF [st.to] = [st.to] F。
        } { 
            NG [st.to] = G [st.to]。
            NF [st.to] = NF [U] -g [st.to] + ngの[U]。
        }
        dfs_2(st.to、U)。
    } 
} 
int型のmain(){ 
    CIN >> N。
    担当者(I、1、N- 1 ){
         int型、U、V、W。
        scanf関数(" %D%D%D "、およびuは、&​​V、およびW)
        VEの[U] .pb({V、W})。
        [V] .pb({U、W})まし。
    } 
    dfs_1(10 ); 
    NF [ 1 ] = F [ 1 ]、NG [ 1 ] = G [ 1 ]。
    dfs_2(10 ); 
    coutの << ANS << てendl;
} 
コードの表示

 

おすすめ

転載: www.cnblogs.com/mountaink/p/11597906.html