P4107 [HEOI2015]うさぎと桜

タイトル説明

長い、長い時間前に、森はウサギのグループに家です。ある日、ウサギは突然桜を見ることにしました。ウサギの森は非常に特別である桜の木。n-1個の枝により接続されている0からN-1までの番号ポイント、n個の分岐点を分岐Nブランチにより桜の木は、我々は、ノードが0である、ルート付きツリー構造としてそれを見ることができますルートノード。このツリーの各ノードは、i番目のノードがC_I桜の花を持って、そのうちのいくつかの桜があります。各ノードは、各ノードI、その子ノードiはチェリー及びMの数を超えることができないノードの数、すなわち、息子(I)+ C_I <= mに対して、最大桜負荷mを有します息子前記(i)はiが葉ノードである場合、息子(i)は= 0、子Iの数を表します。

今、私はいくつかのノードを削除することを望んで、あまりにも多くのウサギの桜の木のノードを考えます。ノードが除去されると、ノードのチェリー及びその息子のノードが削除されたノードの親ノードに接続されています。親ノードも削除されている場合は、最初のノードが削除されていないアップまで、アップ接続していきます。

今、私たちは、ノードの数を削除するまでの最大荷重に違反することなく、ウサギで計算します。

ルートが削除されないことに注意してください、削除されたノードは、負荷に含まれていません。

入力形式

最初の入力2つの正の整数の行、nおよびmは、それぞれのノードの数と最大負荷を表します

二行目のn整数C_I、桜は、i番目のノードの数を表します。

最初の番号の次のn行は、子の数がこのノード、息子の整数を表しK_I次のノードを示すK_I

出力フォーマット

ノードの最大数を表す線の整数を削除することができます。

サンプル入力と出力

入力#1
4 10 
0 2 2 2 4 1 0 4 1 
3 6 2 3 4 
1 9 
1 8 
1 1 
0 
0 
2 7 4 
0 
1 5 
0
出力#1
4

説明/ヒント

データの30%、1 <= N <= 5000、1 <= M <= 100、0 <= C_I <= 100

データの70%を、1 <= N <= 200000、1 <= M <= 2000、0 <= C_I <= 1000

データの100%、1 <= N <= 2000000、1 <= M <= 100000、0 <= C_I <= 1000

その初期データを確実にするために、ノードのチェリー息子の数に各ノードの数が0より大きく、Mを超えません

考え

貪欲。

各ポイントの後に息子と桜が父親に追加、削除、そのC [i]は+息子を行いますので、[i]はiの価格を削除するノードの数です。

各ノードは、自分の子供最小のコストで削除された後、その外観を更新するコスト。

コード

#include <cmath> 
の#include <cstdioを> 
する#include <CStringの> 
する#include <iostreamの> 
する#include <アルゴリズム> 
名前空間STDを使用して、

const int型N = 2000010; 

N INT、M、KNT、ANS。
[N]、[N] C、L [N]、R [N] INT。

読み取りINT(){ 
	= 0をINT、フラグ= 1。
	チャーC = GETCHAR()。
	一方、(C <48 || C> 57){ 
		IF(C == ' - ')フラグ= -1。
		C = GETCHAR()。
	} 
	(C> = 48個の&& C <= 57){ながら
		アウト=うち* 10 + C-48。
		C = GETCHAR()。
	} 
	*フラグを返します。
} 

BOOL CMP(int型のx、int型のY){ 
	戻りC [X] <C [Y]。
} 

ボイドDFSは(今INT){ 
	ため(INT I = 1 [今]; I <= R [今]。
		私は++){ [今や] ++、C。
	}
	ソート(+ 1 [今]、[今] + 1、CMP + rの); 
	以下のために(INT I = 1 [今]; I <= R [今]; ++ I){ 
		IF(C [今] + C [I]] - 1 <= M){ 
			C [今] + = C [I]] - 1。
			ANS ++; 
		}他に
			ブレーク。
	} 
} 

int型のmain(){ 
	//のscanf( "%D%dの"、&N、&M)。
	N = read()は、M = read()は、
	(; iが<= N I ++は、I = 1 INT)するための
		C [i]を読み出します=(); 
	{ため(; iは= <N iは++ i = 1であり、X INT)
		X =リード()。
		L [I] = KNT + 1。
		一方、(x--)
			[++ KNT] =リード()+ 1。
		/ * { 
			KNT ++。
			scanf関数( "%d個"、&[KNT])。
			[KNT] ++; 
		} * / 
		R [I] = KNT。
	} 
	DFS(1)。
	printf( "%d個の\ n"、ANS)。
}

 

おすすめ

転載: www.cnblogs.com/mysh/p/11800801.html