タイトル
コメント
ただ、この質問はまだかなりの混乱を感じて読んで、その後、脳は目を覚まし、再びTarjanの感触を取り戻していない可能性があります。もちろん、あなたが最終的には、ツリーでDPを見つける必要があります。
自身のサブツリー、ブール値G [U] Uはプログラムやサブツリーの数がそれ以外の場合1、ユニークユニーク0で表し、Tを含む最大の利益のルート(以下DP [U] U代表[U] Uの数、Vを表し、[U]はuの値を表します)
最大の利益は、実際にはかなり簡単です計算します。以下のようなビットは、前に行わエアコン完備の教室が、より多くの制限や負の数よりも、対処することは困難ではありません。私たちは一人息子のDP値が[U] -1ヶ月トンを選択する前に、ソートされている、とすぐにそれ以来負の経験を停止することができますので、それぞれの息子は、ルートに戻って取得するために仕上げた後のuを返さなければならないため、Uは、時間を計算します合計値ダウン唯一のマイナスオプションが小さくなります。
それでは、どの治療プログラムはユニークですか?
我々は、U gはそのサブツリープログラムの数は一意である表わすブール配列を開きました。明らかに、以下の3つの条件の下でのプログラムの数だけが一意ではありません。
DP取得息子値0(選挙投票することはできません)
息子が作ったGの値を1(サブツリーZhekeの異なる経路が存在します)
次の選挙は息子と最後に選択の息子ではありませんfは同じですが(交換することができる)の値(私はこの点を無視するとき、それでもA、および弱すぎるデータについて書きました)
その後、オハイオ州、それを再帰的に再びルートからの最後見DP [1]、G [1]を起動。
(パートは本当にありがとうございました、DZN兄を参照して練習を来てほしい〜しません)
コード
1の#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 CONST INT MAXN = 100000 + 5はInf = 2147483647 。 4インラインintはREAD(){ 5 INT S = 0、W = 1 。 6 チャー CH = GETCHAR()。 7 一方(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ')W = - 1 ; CH =GETCHAR();} 8 しばらく(CH> = ' 0 ' && CH <= ' 9 ')S = S * 10 + CH- ' 0 '、CH = GETCHAR()。 9 リターン S * ワット。 10 } 11 INT N、ヘッド[MAXN]、TOT、V [MAXN]、T [MAXN]、DP [MAXN]。 12 BOOL G [MAXN]。 13 構造体ノード{ 14 INT 次へ。 15 }、E [ 2 * MAXN]。 16 ボイド追加(int型、int型B)を{ 17 E [TOT] .TO = B。 18 E [TOT] .next = ヘッド[A]。 19 頭[] = TOT。 20 TOT ++ ; 21 } 22の 空隙 DFS(int型のx、int型FA){ 23 PRIORITY_QUEUE <ペア< 整数、整数 >> Q。// 按照DP值大小排序 24 のために(INT ; I iが= I [x]はヘッド= {Eを[I] .next) 25 のint V = E [I] .TO。 26 であれば(V == FA)を続けます。 27の DFS(V、X) 28 q.push(make_pair(DP [V]、V)); 29 } 30 のint = NUM 0、SUM = 0、ジャッジ= 0 ; 31は 、一方(! - q.empty()&& NUM <T [X] 。1 ) { 32 IF(q.top()まず< 0)BREAK ; // ドラッグが停止直ちに発生 33は、 IF(q.top()==まず。0){ // 0説明した実施形態は、1ではない 34 / / 0又は負、直接バック、寄与することができないのいずれかの後ろに0 35 ジャッジ= 1。; 36 BREAK ; 37 } 38れる SUM + = Q.top()まず; 39 IF(G == [Q.top()SECOND。] 1。 )裁判官= 1。; 40 q.pop(); 41である NUM ++ ; 42れる } 43は、 DP [X] = SUM + V [X]; 44である G [X] = 裁判官; 45 } 46である INT (メイン){ 47 TOT = 1。; 48 T [ 1。 = Infの]; // 自宅に注意が多数取ることができる 49 N- = 読み取り() ; 50 用(INT I = 2; I <= N; I ++)V [I] = (読み取り) 51 のために(INT iは= 2 T [I] =; <I = N I ++) (リード)。 52 のために(INT iは= 1 ; iが<= N- 1、I ++ ){ 53 のint X、Y。 54 X =リード()。Y = READ()。 55 追加(X、Y) 56 追加(Y、X)。 57 } 58 DFS(1、0 ); 59 のprintf(" %dの\ n "、DP [ 1 ])。 60 もし(G [ 1 ])のprintf(" ソリューションは一意ではありません" )。 61 他のprintf(" ソリューションがユニークです" ); 62 リターン 0 ; 63 }
聖歌ブログに幸いなことに、でも聖なる歌。