HDU 1520 Anniversary party(树形dp)

HDU 1520 Anniversary party(树形dp)

树形dp第一题!!!

题意很清晰,思路也很明确。很容易找到根节点,即最大的boss,通过根节点向下dp。

状态转移方程:

  • int to = vec[x][i];
  • dfs(to);
  • dp[x][1] += dp[to][0];
  • dp[x][0] += max(dp[to][1], dp[to][0]);

即对于一个节点。如果它有根节点:

  • 选区本节点;
  • 或者选取根节点的最大权值.
#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

const int N = 6010;

int n;
int value[N];
vector< vector<int > > vec(N);
int boss, emp;
int root;
int non[N];

int dp[N][2];

void init()
{
	memset(value, 0,sizeof(value));
	memset(non, false,sizeof(non));
	memset(dp, 0,sizeof(dp));
}

void find_root()
{
	for(int i = 1 ; i <= n ;i++)
	{
		if(non[i] == false)
		{
			root = i;
			return;
		}
	}
}

void dfs(int x)
{
    for(int i = 0; i < (int)vec[x].size(); i++)
    {
        int to = vec[x][i];
        dfs(to);
        dp[x][1] += dp[to][0];
        dp[x][0] += max(dp[to][1], dp[to][0]);
    }
}

int main()
{
	init();
    cin >> n;

	for(int i = 1 ; i <= n ; i++)	
		{
			cin >> value[i];
			dp[i][1] = value[i];
		}

	for(int i = 1 ; i < n ; i++)
	{
		cin >> boss >> emp;
		vec[emp].push_back(boss);
		non[boss] = true;
	}

	cin >> boss >> emp;

	find_root();

	dfs(root);

	cout << max( dp[root][0] , dp[root][1] );
    return 0;
}
透过泪水看到希望
原文地址:https://www.cnblogs.com/ronnielee/p/9495148.html