【ZJOI2006]バイナリトリコロール

木のDP

トピックポータル

タイトル効果:最大と緑色ノードの最小数を求めて、赤、緑、青の色に染色バイナリツリーノードを所与。

この非常に病気やいくつかのヒントを必要とする問題の成果:

列と観測問題表面の数を入力し、あなたは左と右のサブツリーにその左部分木のいずれかのノードがいくつか知ることができ、そして右の部分木の隣に

そのようなDFSを実行し、第1の左サブツリー検索、ノードLN左サブツリーの数を記録することができる、配列添字LN + 1の数は右のサブツリーのルートであり、右の部分木を検索し、レコード数RNノード、その後、LN + RN + 1が検索する次の点です

 

染色のために、各ノードは、2つのタイプに分けることができる:緑色染料と緑色染色しません

我々はFを作ることができる[i]は[0/1]私は緑/緑の染料、緑色のノードの最大数、FFに染色されていない場合、ノードのサブツリーは、根ざし表す[I] [0/1]同様に、最小

時間[i]が[1] = F [LS [I] [0] +1 F息子Iを有する場合

二人の息子、I、F [i]が[0] = MAX(F [LS [I] [0] + F [RS [I]] [1]、F [RS [I] [0 ] + F [LS [I]] [1])F [i]を[1] = F [LS [I] [0] + F [RS [I] [0] +1

同様に最低

コード:

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
チャー C [ 1000005 ]。
int型のp [ 1000005 ]。
int型のn;
int型LST;
int型 S [ 1000005 ]。
INT [F 1000005 ] [ 2 ]。
int型 FF [ 1000005 ] [ 2 ]。
int型の LS [ 1000005 ]、RS [ 1000005 ]。
INTのビルド(INTのCUR)
{ 
    場合(P [CUR] == 0リターン 1;
    他の 場合(P [CUR] == 1 
    { 
        LS [CUR] = CUR + 1 int型、T =ビルド(CUR + 1 );
        リターン T + 1 ; 
    } 
    
    { 
        LS [CUR] = CUR + 1 int型、T =ビルド(CUR + 1 ); 
        RS [CUR] = CUR + T + 1 int型 TT =ビルド(CUR + T + 1 );
        戻る T + TT + 1を
    } 
} 
のボイドDFS(int型i)を
{ 
    場合(LS [I] =!0 )DFS(LS [I])。
    もし(!RS [I] = 0 )DFS(RS [I]);
    もし(S [I] == 1 
    { 
        F [i]が[ 1 ] = F [LS [I] [ 0 ] + 1 
        FF [I] [ 1 ] = FFの[LS [I] [ 0 ] + 1 
        F [i]が[ 0 ] = MAX(F [LS [I] [ 0 ]、F [LS [I]] [ 1 ])。
        FF [I] [ 0 ] =分(FF [LS [I] [ 0 ]、FF [LS [I]] [ 1 ])。
    }
    もし(S [I] == 2 
    { 
        F [i]が[ 1 ] = F [LS [I] [ 0 ] + F [RS [I] [ 0 ] + 1 
        FF [I] [ 1 ] = FFの[LS [I] [ 0 ] + FF [RS [I] [ 0 ] + 1 
        F [i]が[ 0 ] = MAX(F [LS [I] [ 0 ] + F [RS [I]] [ 1 ]、F [RS [I] [ 0 ] + F [LS [I] [ 1 ])。
        FF [I] [ 0 ] =分(FF [LS [I] [ 0 ] + FF [RS [I]] [ 1 ]、FF [RS [I] [ 0 ] + FF [LS [I] [ 1 ])。
    }
}
INT メイン()
{ 
    CIN >>(C + 1 )。
    N = STRLEN(C + 1 )。
    以下のためにint型私= 1 ; iが<= N; iが++)P [i]は= Cを[I] - ' 0 ' 
    (ビルド1 )。
    以下のためにint型 i = 1 ; iは= N <; iは++ 
    { 
        場合(LS [I] && RS [I])S [I] = 2 ;
        それ以外の 場合(LS [I] && rsの[i]を!!)■[I] = 0 ;
        の[I] = 1 ;
        もし(S [i]を== 0)F [i]を[ 1 ] = FFの[I] [ 1 ] = 1 
    } 
    DFS(1 )。
    // << I << ' '<< F [i]が[0] <<'' << F [i]を[1] << ENDL COUTをするための(iは++; iがn = <I = 1 INT)。
    COUT << MAX(F [ 1 ] [ 0 ]、[F 1 ] [ 1 ])<< '  ' <<分(FF [ 1 ] [ 1 ]、FFは[ 1 ] [ 0 ])<< ENDL。
    リターン 0 ; 
}

使用するGoogle入力方法™本当に難しいです

 

おすすめ

転載: www.cnblogs.com/ssf-xiaoban/p/11614853.html