hdoj3586(木DP)

トピックリンクします。https://vjudge.net/problem/HDU-3586

問題の意味:ツリーの右側、根に到達できない各リーフノードの縁、及びこれらのエッジの重みの一部<=上限マックス、右側及びMよりも小さい、最小ANSの上限、もしを削除します-1出力は満たされません。

アイデア:

  ツリーには、枠消し、DPに属します。列挙上半分Maxは、MaxはDPで満たすために必要な最小値を見つけるために、[U]はuがノードに、Uを除去するために必要なエッジ最小重量をリーフノードにノードuはのサブツリーをされていない表します子ノードv、U-> Vの重み値ワット その後:

  もし最大> W:DP [U] + = DP [V]

  DP [U] + =分([V] DP、W)<=マックスW如果

  リーフノードのU DP [U]はuが非リーフノードのために、infに初期化され、DP [U]を0に初期化され、M + 1に設定infを、DP計算[U]であれば、プロセスDPとして[U]> = INF早期に終了します。各検出の最大、[1] <= mができる唯一のDPを決定します。

ACコード:

書式#include <cstdioを> 
する#include <アルゴリズム>
 使用して 名前空間はstdを、

const  int型 MAXN = 1005 ;
INTのN、M、CNT、ヘッド[MAXN]、INF、マックス、DP [MAXN]。

構造体ノード{
     int型NEX、W、V、。
}エッジ[MAXN << 1 ]。

ボイド ADDE(INT U、INT V、INT W){ 
    エッジ[ ++ CNT] .V = V。
    エッジ[CNT] .W = W。
    エッジ[CNT] .nex = 頭部[U]。
    ヘッド[U] = CNT。
} 

無効 DFS(int型、U、int型のFA){ 
    DP [U] = 0 ;
    int型フラグ= 0 以下のためにint型 ; I I = I =ヘッド[U] {エッジ[I] .nex)
         のint V =エッジ[I] .V、W = エッジ[I] .W。
        もし(== FA V)続けます
        フラグ = 1 
        DFS(V、U); 
        もし(> W 最大)
            DP [U] + = DP [V]。
        
            DP [U] + = 分(DP [V]、W)。
        もし(DP [U]> =  INF){
            DP [U] =infファイル。
            破ります; 
        } 
    } 
    もし(!フラグ)
        DP [U] = INF。
} 

BOOL(解決INT X){ 
    マックス = X。
    DFS(10 );
    戻り DPを[ 1 ] <= M。
} 

int型のmain(){
     一方(のscanf(" %dの%のD "、&​​N、&M)、N || M){ 
        CNT = 0、INF = M + 1 以下のための int型i = 1 ; ++; iが<= N I)
            ヘッド[I] = 0 ;
        以下のためにint型 i = 1 ; iがn <; ++ I){
             int型、U、V、W。
            scanf関数(" %D%D%D "、およびuは、&​​V、およびW)
            ADDE(U、V、W)。
            ADDE(V、U、W)。
        } 
        int型の L = 1、R = 1000年、ミッド。
        一方、(L <= R){ 
            半ば =(L + R)>> 1 もし(解く(MID))、R =半ば1;
            リットル=ミッド+ 1 ; 
        } 
        もし(L == 1001)のprintf(" -1の\ n " );
        のprintf(" %d個の\ n " 、L)。
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/FrankChen831X/p/11469085.html