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;
}
透过泪水看到希望