1. 程式人生 > >#122-[樹形動態規劃]LazyChild黑OJ

#122-[樹形動態規劃]LazyChild黑OJ

Description

LazyChild開了一家“善良OJ”。但大多數人都不知道,這其實是家黑OJ。親愛的同學,請不要驚訝,古時候有黑店,現代為什麼不能有黑OJ呢?每AC一道題,網站便會自動在電腦上安裝一種木馬。LazyChild通過竊取資訊獲取收益(如網遊帳號、OI資料、YuanY和TT的照片等等)。

作為一名資深黑客,老Z某日突然發現,“善良OJ”上的木馬,自己電腦上都沒有。這可十分讓他過意不去。老Z決定通過多A題,來豐富自己電腦的病毒庫。

經過調查,老Z發現,很多木馬是不能共存的。比如“和諧”木馬與“團結”木馬,兩者只能任選其一。然而,老Z是個完美主義者,他想要自己的病毒庫儘可能充實。

老Z不懈的追求最終感動了上天。天上的神仙(半仙?)“牛人雨”給這個問題稍稍降低了一點難度。神仙規定,對於n種木馬,有且僅有(n-1)對不能共存,並且對於每種木馬,都存在至少一個木馬與之不能共存。

老Z不在乎自己AC多少題。請告訴他,他最多能從“善良OJ”上獲取木馬的個數。

Input

第一行,一個正整數n,表示木馬個數。

剩餘(n-1)行,每行一對木馬,表示他們不能共存。(保證相同的木馬可以共存,任意不同兩行的描述不等價)

木馬編號從0至(n-1)

Output

一行,老Z最多獲得木馬的個數。你可以認為開始時沒有任何木馬。

Sample Input

3
0 1
1 2

Sample Output

2

HINT

 

【資料規模】

對於100%的資料,1<=n<=200

如果這個點選了,它的兒子就不能選.

否則隨便.

#include <iostream>
#include <vector>

#define SIZE 210

using namespace std;

vector<int> graph[SIZE];
int dp[SIZE][2];

void dfs(int u, int pre) // DP過程
{
	int i, v;
	
	dp[u][1] = 1; // 邊界條件
	for (i = 0; i < graph[u].size(); ++i)
	{
		v = graph[u][i];
		if (v != pre)
		{
			dfs(v, u);
			dp[u][0] += max(dp[v][0], dp[v][1]); // 如果這個點沒選,它的兒子選不選隨便
			dp[u][1] += dp[v][0]; // 如果這個點選了,它的兒子就不能選.
		}
	}
	
	return;
}

int main(int argc, char** argv)
{
	int n, u, v;
	
	scanf("%d", &n);
	while (--n)
	{
		scanf("%d%d", &u, &v);
		graph[u].push_back(v); // 建圖
		graph[v].push_back(u);
	}
	
	dfs(0, -1);
	
	printf("%d", max(dp[0][0], dp[0][1]));
	
	return 0;
}