HDU 6613 SqurirrelツリーDP

質問の意味:あなたの木を与え、あなたは木の右側のエッジを置くことができますが、今あなたは、ルートを選択することができます、0になるように、できるだけ小さく最大距離の点までのすべてのポイント。根、エッジの最小数の出力からの最大距離以上であれば。

アイデアは:あなたが行動にゼロの右側を入れていない場合は、この質問は、木の直径の中心を見つけることが実際にあります。0一次元マークがゼロとなるエッジのエッジに対する権利を有する上げするかどうかを考えるのは簡単です、操作可能になるがあります。私たちは、1への答えがルートで計算することもできます。DP [i]が[0] Iをルートとするサブツリーの最大エッジ量から変更されていない設定し、DP [I] [1]パスは0最も長くなる右コラージュ後バール最長経路のこの最小長さ。私たちは右のバー後のコラージュ最長パスがゼロでは長い時間の長いパスを消滅してしまうかもしれないとなるため、最長パスは、十分ではないようだ知っていることがわかりました。私たちは長いパスを維持する必要があるので、次の時間。だから我々は最初、私はサブツリー最長経路と第2経路の長さ、および最長パスと長い修正後の二次パスのルートである最小の長さを気にするのに必要なDFS寸法を渡すとき。ライン上で直接修正、メンテナンスなしで最長の時間パスと長いパスのため。それでは、どのようにそれを修正最長パスの最小の長さを維持するには?1:iとjの間のエッジを削除します私たちは、私が最も長いパスと隣接する点j(jは、iの子である)ポイントは、2つの可能性がものを記録する必要があります。2:最小エッジ削除は、以前の点iとjの間のエッジの辺の重みと一緒になっていました。(:アップ、1:チーフ0)(1:レビューベルト、0:変更しない)最小の長さは、DP [I DP [i]が[0] [1] iが最長パスのルートで設定] [0] [1] =分(DP [j]は[0] [0]、MAX(DP [j]は[0] [1]、DP [J] [1] [0])+ W)。大臣の道同様に利用できます。その後、我々は答えのルートであるために来ることができます。ANS =分(DP [1] [0] [1]、DP [1] [1] [0])。今交換法、回答の親ノードの方向から、すなわち、寄与によりルートのルート解答で算出他の点を考慮する。私たちは、親の影響を考慮してください。セットF iは(と修飾/変更なし)のパスの方向によって形成された親ノードのルートの最大長さである[i]は[0/1]、我々はiは、親回答のルートとして計算される時であります拠出金は、私が考えることを、考慮にライン上のノードの方向を撮影している親ノードもエッジを修正する、またはサブツリーを変更するために、親ノード方向側、または側を修正するのですか?これは、計算の答えを置きます。[I] [0]と、f fを維持する方法[i]の[1]それは?最も長い距離f iと親サブツリーが最大距離I maxおよび右側プラス親ノードを取る親ノードから[I] [0]肯定的な方向。最も長い距離サブツリーは、私が含まれていないので、私たちは特別な裁判官にそれを移しました。そこで問題は、私たちの時代には、私はどのように行うのに長い距離のポイントは場合には、されているのですか?したがって、一つの第三の当量が少なく、米国前すなわち初回通過DFS最大値を維持する必要性、長い時間、3番目に長い距離を長い距離を維持しました。F [i]が[1]に列挙された変更を考慮して、同じであるエッジ(親側方向、側方向サブツリー)に移しました。

コード:

#include <ビット/ STDC ++ H> 
に#define PII対<整数、整数> 
名前空間stdを使用。
const int型MAXN = 200010; 
PII DP [MAXN] [3] [2]; //点、第几远、不删边/删边
INT F [MAXN] [2]; //父亲节点来的、不删边/删边
INT D 【MAXN]。
ベクター<PII> G [MAXN]。
int型のANS、POS; 
ボイド追加(int型のx、int型のY、int型Z){ 
	G [X] .push_back(make_pair(Y、Z))。
	G [Y] .push_back(make_pair(X、Z))。
} 
ボイドDFS1(int型のx、int型FA){ 
	(オートY:G [X])のために{ 
		(y.first == FA)続行。
		DFS1(y.first、X)。
		D [y.first] = y.second。
		(DP [y.first] [0] [0] + 1次回y.second> = DP [X] [0] [0] 1次回){場合
			DP [X] [2] [0] DPを= [X ] [1] [0]。
			DPは、[X] [1] [0] = DP [X] [0] [0]。
			DP [X] [0] [0] = make_pair(DP [y.first] [0] [0] + 1次回y.second、y.first)。
		}そうであれば(DP [y.first] [0] [0] + 1次回y.second> = DP [X] [1] [0] 1次回){ 
			DP [X] [2] [0] = DP [X] [1] [0]。
			DP [X] [1] [0] = make_pair(DP [y.first] [0] [0] + 1次回y.second、y.first)。
		}そうであれば(DP [y.first] [0] [0] + 1次回y.second> = DP [X] [2] [0] 1次回){ 
			DP [X] [2] [0] = make_pair (DP [y.first] [0] [0] + 1次回y.second、y.first)。
		} 
	} 
	int型TMP = DP [X] [0] [0] .second。
	DP [X] [0] [1] = 1次回分(DP [TMP] [0] [0] 1次回、MAX(DP [TMP] [0] [1] 1次回、DP [TMP] [1] [0] 1次回)+ D [TMP])。
	TMP = DP [X] [1] [0] .second。
	DP [X] [1] [1] = 1次回分(DP [TMP] [0] [0] 1次回、MAX(DP [TMP] [0] [1] 1次回、DP [TMP] [1] [0] 1次回)+ D [TMP])。
}
ボイドDFS2(int型のx、int型FA){ 
	int型TMP =分(MAX(F [X] [0]、MAX(DP [X] [0] [1] 1次回、DP [X] [1] [0] 1次回))、MAX([X] [1]、DP F [X] [0] [0] 1次回))。
	IF(TMP <ANS){ 
		ANS = TMP。
		POS = xで。
	}他(TMP == ANS){もし
		POS =分(POS、X)。
	} 
	のための(自動Y:Gは、[X]){ 
		IF(y.first == FA)続けます。
		IF(y.first == DP [X] [0] [0] .second){ 
			F [y.first] [0] = MAX(DP [X] [1] [0] 1次回、F [X] [0])+ y.second。
			F [y.first] [1] =分(MAX(DP [X] [1] [0] 1次回、[X] [0])、分(最大F(F [X] [0]、MAX( DP [X] [1] [1] 1次回、DP [X] [2] [0] 1次回))、MAX(DP [X] [1] [0] 1次回、F [X] [1] ))+ y.second)。
		}他{ 
			F [y.first] [0] = MAX(DP [X] [0] [0] 1次回、[X] [0] F)+ y.second。
			(DP [X] [1] [0] == .second y.first)であれば{ 
				[y.first] [1] =分(MAX(DP [X] [0] [0] [F、fは1次回X] [0])、分(MAX([X] [0]、MAX(DP [X] [0] [1] 1次回、DP [X] [2] [0] 1次回)F)、最大(DP [X] [0] [0] 1次回、F [X] [1]))+ y.second)。
			}他{ 
				F [y.first] [1] =分(MAX(DP [X] [0] [0] 1次回、[X] [0])、分(MAX(F F [X] [0] 、MAX(DP [X] [0] [1] 1次回、DP [X] [1] [0] 1次回))、MAX(DP [X] [0] [0] 1次回、F [X] [1]))+ y.second)。
			} 
		} 
		DFS2(y.first、X)。
	} 
} 
int型のmain(){ 
	int型T、N、U、V、W。
// freopenは( "in.txt"、 "R"、STDIN)。
// freopenは( "out.txtを"、 "W"、STDOUT)。
	scanf関数( "%のD"、&T)。
	(T--){一方
		のscanf( "%d個"、&N); 
		(I = 1をint型のために、私は<= N。
			memsetの(DP [i]は、0、はsizeof(DP [I]))。
			memsetの(F [i]が、0、はsizeof(F [I]))。
			D [I] = 0; 
		} 
		{ため(iは++; iがn <I = 1 INT)
			のscanf( "%D%D%D"、&U&V、およびW)
			(U、V、W)を加えます。
		} 
		DFS1(1、0); 
		ANS = MAX(DP [1] [0] [1] 1次回、DP [1] [1] [0] 1次回)。
		POS = 1。
		DFS2(1、0); 
		printf( "%D%D \ n"は、POS、ANS)。
	} 
}

  

 

おすすめ

転載: www.cnblogs.com/pkgunboat/p/11420039.html