トピックリンクします。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(1、0 ); 戻り 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 。 }