题目链接:
http://codevs.cn/problem/1380/
分析:树形dp 模板题
遍历的时候记录参加或不参加的值,比较最大即可。但需要用并查集或其他方法找到起始点(即树的根)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define maxn 6500
int n ;
int hi[maxn];
int fa[maxn];
int dp[maxn][2];//[0]代表参加
vector<int>E[maxn];
void dfs(int u,int f)
{
dp[u][0] = hi[u];
dp[u][1] = 0;
// printf("%d\n",dp[u][0]);
for(int i = 0 ; i < E[u].size() ; ++i)
{
int v = E[u][i];
if( v == f )continue;
dfs(v,u);
dp[u][0] += dp[v][1];
dp[u][1] += max(dp[v][0],dp[v][1]);
}
}
int main()
{
while( cin >> n )
{
for(int i = 1 ; i <= n ; ++i)
{
scanf("%d",&hi[i]);
}
for(int i = 0 ; i < n ; ++i)
{
int k,l;
scanf("%d %d",&l,&k);
E[k].push_back(l);
fa[l] = k;
}
int s = n;
while( fa[s] != 0 )
{
s = fa[s];
}
//printf("%d\n",s);
dfs(s,0);
cout << max( dp[s][0] , dp[s][1] )<< endl;
}
}