プレミアムケーブルテレビネットワークは重要なサッカーの試合を放送する予定。彼らは、ネットワークをブロードキャストし、ユーザ端末は、木構造を構成し、このツリーのルートは、サッカーゲームシーンに位置し、各ユーザ端末のための木の他の内部ノードのための通過点を残します。
中継局から中継局、及び中継局からの信号の送信に全てのユーザ端末のコストに知られており、放送伝送信号の総コストは、コストの和に等しいです。
各ユーザーは、現在の料金は、このエキサイティングなサッカーの試合を見たいと思うの準備、ケーブルテレビネットワークは、ユーザーがユーザーに信号を提供信号を提供しないことを決定する権利を持っています。
解決策を見つけるためのプログラムを書くことは、ユーザーがお金を失うことなく、可能な限りケーブルテレビ放送を視聴することができます。
入力形式
入力ファイルの最初の行は2≤N≤3000,1≤M≤N-1、Nは、Mは、ユーザ端末である、ケーブルテレビネットワーク全体のノードの総数で2スペースで区切られた整数NおよびMを含有します番号。
ツリーのルートである第1の中継局が1番号付けされ、他の放送局は、NM、N.ユーザ端末番号NM + 1に2の番号が付け
NM後続の行それぞれは、 - 以下の形式で、i番目の中継局を示すデータ放送局、iは、+ 1ラインデータ:
K A1 C1 A2 C2 ...準備物語
Kは、各ノードは整数AとCの対に対応する、中継局におけるKのアクセスノード(中継局または加入者)を表し、Aはノード番号を表し、Cは、現在の中継局のコストを表すノードAに信号を送信します。ターンの最後の行は、すべてのユーザーが試合を観戦し、金額を支払うために準備されることを意味しています。
出力フォーマット
ライン出力ファイルは、問題の上に必要なユーザの最大数を表す整数を含んでいます。
サンプル入力と出力
5 3 2 2 2 5 3 2 3 2 3 4 3 4 2
2
説明/ヒント
サンプルの解釈
示されるように、5つのノードがあります。①、ルートノード、すなわちライブステーション、転写ステーション②ある③④⑤UE、Mの合計数N-M + 1からNまでの金額に、彼らは、ゲームが3で見るように調製されます、 4,2、信号は②ノード間の①から送信されてもよい、コストは2であり、また⑤ノードに信号を送信することができ、コスト(第2段目に示すデータ)図3は、ノード信号に②ノードから送信することができます、コスト2を③ポイント。また、ノード④、(第3段目に示すデータ)3のコストに信号を送信することができる、もしユーザの全て(③④⑤)ファンシーゲームことができ、信号伝送の総コスト:
2 + 3 + 2 + 3 = 10、ユーザーは= 9 3 + 4 + 2の総コストを支払うことを喜んでいるよりも大きい、ケーブルネットワークは、お金を失うが、唯一の2人のユーザーがゲームは③④お金を失っていない見ることができます。
私はアルゴリズムの複雑さを記述することが可能で、叫んだ、彼はアルゴリズムのn ^ 3(と思う)、最大の賃金アップポイント60msの、例えば、N ^ 2のような高速なアルゴリズムを書きました。
オンラインコードはまた、N ^ 2のために、この問題の複雑さの証拠を見つけることができませんでした長い時間のために誰かを見つけるためのアイデアです。
書式#include <キュー> の#include < 文字列 > の#include <cstdioを> する#include <CStringの> の#include <iostreamの> の#include <アルゴリズム> 使用して 名前空間はstdを、 #defineは長い長いっ CONST LL INF = 1000000000000000000ll。 const int型 MAXN = 3005 ; int型DP [MAXN] [MAXN]。 int型のCNT [MAXN]。 int型のヘッド[MAXN * 2 ]乃至[MAXN * 2 ]、NE [MAXN * 2 ]、ヴァル[MAXN * 2 ]、TOT = 0 。 INTのN、M、K。 int型、C。 int型 ANS = 0 ; インラインボイドが追加(INT U、INT V、int型のC){ 【TOT]へ = V。 NO [TOT] = 頭部[IN]。 ヴァル[TOT] =のC。 ヘッド[U]は ++ TOTを= 。 【TOT]へ = U。 NE [TOT] = 頭部[V]。 ヴァル[TOT] =のC。 ヘッド[V] = TOT ++ 。 } ボイド DFS(int型、Uをint型FA)を{ DP [U] [ 0 ] = 0 。 以下のために(int型 I =ヘッド[U]; I =! - 1 ; I =のNE [I]){ int型 V = 乃至[I]。 もし(== FA V)続けます。 DFS(V、U); CNT [U] + = CNT [V]。 用(INT J = CNT [U]、T = CNT [V]; J; J - 、T = 分(CNT [V]、J)) のための(INT K = 1 ; K <= T; ++ k個) DP [U] [J] = MAX(DP [U] [J]、DP [U] [JK] + DP [V] [K] - ヴァル[I])。 } } INT {main()の scanf関数(" %d個の%のD "、&N、&M)。 memsetの(頭、 - 1、はsizeof (ヘッド))。 memsetの(DP、128、はsizeof (DP))。 以下のために(int型 I = 1 ; I <=ナノメートル; iは++ ){ scanf関数(" %のD "、&K)。 用(INT J = 0 ; J <K、J ++ ){ scanf関数(" %d個の%のD "、&A&C)。 (I、C)を追加。 } } 用(int型 I = N-M + 1 ; iが<= N; iが++ ) scanf関数(" %のD "、およびDP [I] [ 1 ])、CNT [I] = 1 。 DFS(1 - 1 )。 以下のために(int型 I = mを、I> = 0 ; i--)であれば(DP [ 1 ] [I]> = 0 ){ printf(" %d個の\ nを"、i)は、破ります; } リターン 0 ; } / * 2 1 1 2 2 3 * /