#(木バックパック/多分岐ツリーナップザック問題)羅区P1273ケーブルネットワーク(増加+ /地方の選挙 - )

タイトル説明

プレミアムケーブルテレビネットワークは重要なサッカーの試合を放送する予定。彼らは、ネットワークをブロードキャストし、ユーザ端末は、木構造を構成し、このツリーのルートは、サッカーゲームシーンに位置し、各ユーザ端末のための木の他の内部ノードのための通過点を残します。

中継局から中継局、及び中継局からの信号の送信に全てのユーザ端末のコストに知られており、放送伝送信号の総コストは、コストの和に等しいです。

各ユーザーは、現在の料金は、このエキサイティングなサッカーの試合を見たいと思うの準備、ケーブルテレビネットワークは、ユーザーがユーザーに信号を提供信号を提供しないことを決定する権利を持っています。

解決策を見つけるためのプログラムを書くことは、ユーザーがお金を失うことなく、可能な限りケーブルテレビ放送を視聴することができます。

入力形式

入力ファイルの最初の行は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に信号を送信します。ターンの最後の行は、すべてのユーザーが試合を観戦し、金額を支払うために準備されることを意味しています。

出力フォーマット

ライン出力ファイルは、問題の上に必要なユーザの最大数を表す整数を含んでいます。

サンプル入力と出力

入力#1
5 3 
2 2 2 5 3 
2 3 2 4 3 
3 4 2
出力#1
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人のユーザーがゲームは③④お金を失っていない見ることができます。

 考えます:
分析からアップ、親ノードのすべてのリーフノードに対して、親ノードがルートノードから最大値に達した:親ノードのルートを右リーフノード値の値Xi、リーフノードのYI、maxΣは(yi-ありますXI);
損失を確保していない一方で、(可能な接続の息子と同じくらい)の値を最大化するために、任意のリーフノード、親ノードを選択し、残りのノードというお金の最大量を格納する必要があります
この状態は、出てきました
F [i] [j]が親ノードIに示し、jは--- 1子の最大数のためのお金の残りの数であります
又はF [i]は[J]私は2人の息子---お金jの残量があり、親ノードによって表されます
1を押してみてください。
[I] [J] = f maxが、AIを息子設定されている状態Iに対する(F [I] [J]、[AI] F [J +パス[I] [I]]])。
すべてのリーフノードiについて、F [i]が[お金[I] = 1。
2プッシュ:
初期化:すべてのリーフノードiについては、[I] [1]お金= F [i]は、
F [I] [J] = MAX(F [I] [J]、F [i]が[JK] + F [OR] [K])。

正解:

DPツリー(パケットリュックサック)

自分の理解についての講演

1. DP [I] [J]の意味を特定し、お金の最大値を取得し、各ノードにバックパックのパケットを行うために、ユーザから選択されたノードI、Jを表します。

2.グループ化はどのようにバックパックを見ているのですか?まず、ルートノードのすべてのユーザのサブツリーの点の数に対応したパックの総容量(DP [I] [J] jは、それに接続されているすべてのユーザーの数を超えることはできません)。Nから選択される基から選ばれる基、元素から選ばそれぞれ、...二人のユーザとして子ノードの次に、それぞれ。

3.転送方程式DP [I] [J] = MAX(DP [i] [j]は、DPは、[] [JK] + DPは[V] [k]は - このエッジのコスト)i、jは説明しません、Vこのグループに列挙(すなわち、息子I)において、kは、このグループ内の要素の列挙を表す:k番目のユーザが選択されます。

4.最終的な出力DP [1]〜[I]> = Iの最大値が0である場合、逆列挙。

ACコード:

#include <iostreamの>
する#include <cstdioを>
する#include <CStringの>
に#defineための式(I、B)(iは= int型、iは= Bを<; I ++の)ため//简化代码
の#define MAXN 3001
名前空間stdを使用して;
N INT、M。
int型DP [MAXN] [MAXN]、valの[MAXN]。
インラインint型MAX(INTのx、int型のY)//手写MAX、MIN函数
{
X> Yを返すX:Y;?
}
インラインINT分(int型のx、int型のy)は
{
X <Yを返すX:Y;?
}
インラインint型リード()//读入优化
{
チャーCH。
一方、((CH = GETCHAR())< '0' || CH> '9')。
int型のres = CH-48;
一方、((CH = GETCHAR())> = '0' && CH <= '9')
のRES =のRES * 10 +-'0' CH。
解像度を返します。
}
構造体ノード{//邻接表、不赘述
INT次。
へのint;
int型のw;
};
ノードE [MAXN * 2 + 10];
int型のヘッド[MAXN * 2 + 10]、NUM;
ボイドaddedge(INT INTの重量のために、INT、から)
{
E [NUM ++] = .next【から】ヘッド;
E [NUM] .TO =であり;
E [NUM] .W =重量、
ヘッド【から】NUM =;
}
処理ノードのINT DFS(INT U)// DP最も重要な関数U、uがノードを返しますクライアントの最大数
{
(U> nm)のIF //ノードがリーフノードである場合、U、すなわちクライアントポート
{
DP [U]ヴァル= [U] [1]; //だけ顧客の存在を提供することができ値ヴァル[U]
リターン1; //顧客数を返し1
}
int型SUM = 0、T; Uは、@ SUM統計情報(すなわち、パケットのナップザック容量)、Tが格納されているクライアント・ノードの最大数
//現在バックパックをグループ化するすべての人の息子を介して顧客の子ノードの数は、すべての息子の分類、
(INT I =ヘッド[Uため //; I I = E [I] .next]) すべての人の息子、すなわちパケットリュックすべてのカテゴリ
{
int型V = E [I] .TO; //
T = DFS(V); //グループの息子の能力を決定
和+ = Tと、統計の//総容量
用(INT J =和あり、j > 0; J - )// パケットのバックパック、バックパックの外側体積列挙
{
用(INT 1 = K、K <= T; K ++)//内部グループ列挙息子ケース
//実際には、また、EHバイナリ最適化することができます!
IF(JK> = 0)//息子は上から転送することができる場合
、DP [U] [J] = MAX(DP [U] [J]、DP [U] [JK] + DP [V] [K] ; [I] .W)-e
} //更新値その後、保存されたノードuは、顧客のJKプラスk個のVの顧客ノードが提供する、マイナスの
ことができます//通行料金!
}
戻りSUM; //リターン
}

メインINT()
{
memsetの(DP、〜は0x3F、はsizeof(DP));ピーク値DPに割り当て//配列
; N- =読む()、M =読む()
については、(I 1、NMを,.)
{
int型のサイズ=読み取る();
について(J ,. 1、サイズ)//読み取り側
{
int型V =(読み取り)、Wが読み取ら=();
addedge(I、V、W);

}
}
について(I、M + N-- 1、N)//読み取るクライアントポート
ヴァル[I])(読み取る。=;
私は1 ,.ため、N-)
DP [I]は[0] = 0;
。DFS(1);
(INT I =メートル; I> 。1 =; i--)
[1]顧客に会うないIF(DP [I]> = 0)//最初の損失!
{
のprintf( "%のD"、I); //出力することができます!
BREAK;
}

0を返します。
}

多分岐ツリーナップザック問題:

https://blog.csdn.net/no1_terminator/article/details/77824790

https://blog.csdn.net/qq_30802053/article/details/78154266

https://blog.csdn.net/u013582254/article/details/78409114

おすすめ

転載: www.cnblogs.com/little-cute-hjr/p/11432704.html
おすすめ