P3621 [[APIO2007]風鈴]

この物語は、すべてJiekeの暴力(ドゥ)力(劉)DPを教えてくれる。
まず第一に、効果のタイトルは、私たちは彼に完全なバイナリツリーに変身するいくつかの方法を与えられたことです。我々は、すべての完全なバイナリツリーのリーフノードは、一方が鎖であり、他方は他方の鎖の深さよりも大きいチェーン1上の点の深された二本鎖であり、2つだけの場合があるべきで、互いに接続されています。
オーダーDP(i、j)がiノードの状態がjにおける動きの最小数で表します。
ステータスは何も3種類:
チェーン1深いです。
2.浅いチェーン。
3.二つの鎖。
私たちは、木のサブツリー内のリーフノードのすべての深さは上の値を、対応する場合、状態1と状態2のために、何の再帰がダウンして、ちょうど見ないようにしてポイントを、どんなにモバイル、深さは、常に同じではないことに注意してくださいそれは。

第三の場合は、以下の6例転送である:
1.1 2 +
2.1 3 +
3.3 + 2
4.2 + 1(1)
5.3 + 1(1)
6.2 + 3(1)に加えて、左右のサブツリーを指し交換過ごし

以下のコードを:

#pragma GCCの最適化( "Ofast、高速数学")
の#pragma GCC対象( "AVX、AVX2")
の#pragma GCCの最適化( "O2")
の#include <ビット/ STDC ++。H> 
の#defineのGC PA == PB &&( PB =(PA = BUF)+関数fread(BUF、1,1- << 17、STDIN)、PA == PB)EOF:* PA ++ 
静的チャーBUF [1 << 17]、* PA(BUF)、* PB (BUF)。
インラインint型リード(){ 
	F = 1、INT S = 0を登録します。
	チャーCH(GC)を登録します。
	一方、(CH < '0' || CH> '9')CH == ' - ' F = -1、CH = GC:CH = GC。
	一方、(CH> = '0' && CH <= '9')S = sの* 10 + CH-48、CH = GC。
	リターンS *のF; 
} 
名前空間stdを使用。
構造体yuansu { 
	int型X、Y。
}扁[200005]。
int型ミネソタ州(10000000)。
int型B [100005]、DUI [100005]、deepth [100005]。
[100005] LEF int型、リグ[100005]。
int型のF(1)。
整数nを、X、Y。
可能INT [100005] [2]。
int型CMP(yuansu、yuansu B){ 
	戻りAX <BX。
} 
INT分(INT A、INT B){ 
	?<B戻り:Bと、
} 
BFS(){int型
	int型ヘッド(1)、尾部(2)
	B [0] = Bは、[1] = 1。
	DUI [1] = 1。
	(!ヘッド=尾){ながら
		I(DUI [ヘッド])がINT。
		もし{(LEF [I]!)
			IF(ミネソタ州= 10000000!){ 
				IF((ミネソタ州> deepth [DUI [ヘッド] + 1)||(ミネソタ州<deepth [DUI [頭]] - 1))リターン1 ; 
			} 
			IF(ミネソタ州= deepth [DUI [ヘッド] &&ミネソタ州= 10000000!)F = 0。
			ミネソタ州=分(ミネソタ州、deepth [DUI [頭部])。
		} 
		(!リグ[I])であれば{ 
			IF(!ミネソタ州= 10000000){  
				IF((ミネソタ州> deepth [DUI [ヘッド] + 1)||(ミネソタ州<deepth [DUI [頭]] - 1))リターン1;
			} 
			IF(!ミネソタ州= deepth [DUI [ヘッド] &&ミネソタ州= 10000000)、F = 0。
			ミネソタ州=分(ミネソタ州、deepth [DUI [頭部]]); 
		} 
		IF {(!B [LEF [I])
			DUI [尾部] = LEF [I]; 
			deepth [DUI [尾] = deepth [DUI [ヘッド] + 1; 
			尾++; 
		} 
		IF {(!B [RIG [I])
			DUI [尾部] = RIG [I]; 
			deepth [DUI [尾] = deepth [DUI [ヘッド] + 1; 
			尾++ ; 
		} 
		ヘッド++; 
	} 
	戻り0; 
} 
ボイドDFS(INT淀){ 
	IF {(LEF [ディアン]!)
		IF(deepth [ディアン] ==ミネソタ州)
			の可能性[ディアン] [0] = 1; //場合ポイント不可能な浸透状態を含むサブツリーの光の点として、点(すなわち、状態0)
			の可能な[ディアン] [1] = 1; 
	} 
		そう
			考え[ディアン] [1] = 1。。。 
	{(RIG [ディアン]!)IF
		IF([ディアン] deepth ==ミネソタ州)
			可能[ディアン] [0] = 1;  
		int型のANS(100000000)。
	} 
	{([ディアン] LEF)であれば
		、DFS([ディアン] LEF)。
		可能[ディアン] [0] | =可能[ディアン] LEF] [0]。
		可能[ディアン] [1] | =可能[ディアン] LEF] [1]。
	} 
	IF(リグ[ディアン]){ 
		DFS(リグ[ディアン])。
		可能[ディアン] [0] | =可能[リグ[ディアン] [0]。
		可能[ディアン] [1] | =可能[リグ[ディアン] [1]。
	} 
	を返します。
} 
ボイドchushihua(){ 
	DFS(1)。
	返します。
} 
INT violence_dp(INTディアン、INT ZT){ 
	IF(ZT == 0 || ZT == 1){ 
		(!可能[ディアン] [ZT])であれば0を返します。
		他に100000000を返します。
	}他{ 
		IF(LEF [ディアン] == 0 &&リグ[ディアン] == 0)100000000を返します。
		それ以外の場合(![ディアン] &&リグLEF [ディアン]){
			IF(deepth [ディアン] ==ミネソタ州){ 
				ANS =分(ANS、violence_dp(リグ[ディアン]、0)+1); // 1 + 0(+1)
				ANS =分(ANS、violence_dp(リグ[淀]、2)+1); // 1 + 2(+1)
			}他{ 
				ANS =分(ANS、violence_dp(リグ[ディアン]、1)); // 0 + 1つの
				ANS =分(ANS、violence_dp(リグ[ディアン]、2)); // 0 + 2 
			} 
		!}そうであれば(LEF [ディアン] &&リグ[ディアン]){ 
			IF(deepth [ディアン] ==ミネソタ州){ 
				ANS =分(ANS、violence_dp( LEF [ディアン]、0)); // 0 + 1つの
				ANS =分(ANS、violence_dp([ディアン] LEF 2)); // 2 + 1 
			}他{ 
				ANS =分(ANS、violence_dp(LEF [淀]、1)+1); // 1 + 0(+1)
				ANS =分(ANS、violence_dp(2)+1)、[ディアン] LEF; // 2 + 0(+1)
			} 
		}他{
			ANS =分(ANS、violence_dp(LEF [ディアン]、0)+ violence_dp(リグ[ディアン]、1)); // 0 + 1つの
		Y =読み取り();
			ANS =分(ANS、violence_dp(LEF [ディアン]、2)+ violence_dp(リグ[ディアン]、1)); // 2つの+ 1つの
			ANS =分(ANS、violence_dp(LEF [ディアン]、0)+ violence_dp(リグ[ディアン]、2)); // 0 + 2つの
			ANS =分(ANS、violence_dp(LEF [ディアン]、1)+ violence_dp(リグ[ディアン]、0)+1); // 1 + 0(+ 1)
			ANS =分(ANS、violence_dp(LEF [ディアン]、1)+ violence_dp(リグ[ディアン]、2)+1); // 1 + 2(+1)
			ANS =分(ANS、violence_dp(LEF [淀]、2)+ violence_dp(リグ[ディアン]、0)+1); // 2 + 0(+1)
		} 
		戻りANS。
	} 
} 
int型のmain(){ 
	freopenは( "mobiles.in"、 "R"、STDIN)。
	freopenは( "mobiles.out"、 "W"、STDOUT)。
	N =読み取ります(); 
	以下のために(INT i = 1; iが<= N; iは++){ 
		X =)(読み取ります。
		(X> 0){もし
			[I] = xでLEF。
		} 
		であれば(Y> 
		} 
	} 
	IF(BFS()){ 
		1 - COUT <<; 
		0を返す; 
	} 
	chushihua(); 
	IF(F){//判定ではありません完全なバイナリ
		COUT << 0; 
		戻り0; 
	} 
	IF(violence_dp(1,2)> 10000000)COUT << - 1; 
	他のCOUT << violence_dp(1,2); 
	戻り0; 
}

 


    }
    Chushihua();
    IF(F){//判定が満杯バイナリない
        COUT << 0、
        0を返す;
    }
    。(violence_dp(1,2)> 10000000)COUT << IF - 1;
    他のCOUT << violence_dp (1,2);
    戻り0;
}

おすすめ

転載: www.cnblogs.com/thedreammaker/p/10986448.html