トピックへのリンク:https://www.luogu.org/problem/P3177
タイトル説明
Nツリーの点の数があり、ツリーは、側辺の重みを有しています。0からNのKにあなたの正の整数を与えるためには、黒色染色した木、および他のNK着色白点でK点を選択しなければなりません。すべての点染色した後、あなたは一緒にすべての2つの黒点と白色点二十から二便益の間の距離の間の距離を取得します。Q.最大のメリットは何ですか。
入力形式
最初の行は二つの整数N、Kが含まれています 次いで、N-1は、3つの行の各正の整数のFR、DISに、ツリー内のDIS(FRへ)のエッジ長の存在を示します。入力はすべての点が聯通の間にあることを確認します。
出力フォーマット
出力の最大の利益を表す正の整数。
サンプル入力と出力
入力#1
3 1 1 2 1 1 3 2
出力#1
3
説明/ヒント
データの100%、0 <= K <= N <= 2000
問題解決のアイデアは:まず、我々は答えの側に電流寄与、W =辺の長側の寄与を計算することができますiが最大値j黒のドットを塗っ[i] [j]がサブツリーにある状態のDPを設定します*数*黒ドット数白ドットの他側*番号の側縁の白色点の両側の黒ドット+辺の長さ*の数の他側端部は、次いで、状態遷移を行うことができるが。それは、例えば、私たちは子ノードの現在のサブツリーに列挙し、転送は違法な状況をコーティングする点を決定することが必要であることは注目に値する、我々はそれが黒い点が含まれて列挙し、その後、我々は他に子供を必要とします黒点を述べるが、他のサブツリーの合計サイズがJ未満の場合 - - ツリーは、jの合計を選択した後、1、状態は明らかに正当ではないので、我々は、ケースを削除する必要があります。(私はWAが..QAQ泣い思いませんでした)
#include <ビット/ STDC ++。H> 名前空間stdを使用。 const int型MAXN = 2E3 + 10。 typedefの長い長いLL。 LL DP [MAXN] [MAXN]。 N INT、K。 構造体ST { 次へint型。 ヴァルLL; } STM [MAXN * 2]。 int型のCNT; int型のヘッド[MAXN]。 int型の合計[MAXN]。 無効アドオン(U、int型のVをint型、LLのval){ STM [CNT] .TO = V。 STM [CNT] .next =頭部[U]。 STM [CNT] .val =ヴァル。 ヘッド[U] = CNT ++。 } 空DFS(今のint、int型のFA){ 和[今] = 1。 {ための式(I = STM [I] .next;〜I I =ヘッド[今] INT) = STM [I] .TOにINT。 もし(FAを==に)続けます。 DFS(今に); [へ] [今] + =和を合計します。 } } 空DFS1(今のint、int型のFA){ DP [今] [0] [今] DPを= [1] = 0; //この2つの状態確かに正当な {ための式(I = STM [I] .next;〜I I =ヘッド[今] INT) = STM [I] .TOにINT。 LLヴァル= STM [I] .val。 {(FAを==する)場合 持続する; } DFS1(今に); { - (J; J> = 0 INT J =分([今]和、k))を用 (INT m = 0であり; m [する<= J && M <=和; M ++)のために{ 場合(DPは、[今] [JM] == - 1)継続; //現在の状態遷移が正当であるか否かを判定する DP [今] [J] = MAX(DP [今] [J]、DP [今] [JM] + DP [M] +ヴァル* m個の*(キロメートル)へ] +ヴァル*(和[に対する] - M)*(NK-合計)M + [します])。 } } } } {int型のmain() あなたと、V。 ヴァルLL; CNT = 0; memsetの(頭、-1、はsizeof(ヘッド))。 memsetの(DP、-1、はsizeof(DP))。 scanf関数( "%d個の%のD"、&N&K)。 以下のために(INT i = 1; iがn <; iは++){ scanf関数( "%D%D%LLD"、&U&V、およびヴァル)。 (U、V、ヴァル)を追加します。 (V、U、val)で追加します。 } DFS(1、-1)。 DFS1(1、-1)。 printf( "%LLDする\ n"、DP [1]〜[K])。 0を返します。 }