您的位置:首页 > 其它

[luoguP1352] 没有上司的舞会(DP)

2017-05-04 16:12 274 查看

传送门

 

树上的dp,从底向上dp就行。

设dp[u][0]表示不选节点 u 的最大值,dp[u][1]表示选节点 u 的最大值。

则状态转移方程为:

dp[u][0] = ∑max(dp[v][1], dp[v][0])

dp[u][1] = ∑dp[v][0]  + val[u]

(节点v是节点u的孩子)

 

——代码

#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 12001

using namespace std;

int n, cnt;
int head[MAXN], to[MAXN], next[MAXN], val[MAXN], f[MAXN], r[MAXN], dp[MAXN][2];

inline void add(int x, int y)
{
to[cnt] = y;
next[cnt] = head[x];
head[x] = cnt++;
}

inline void dfs(int u)
{
int i, v;
dp[u][1] = val[u];
for(i = head[u]; i != -1; i = next[i])
{
v = to[i];
if(v != f[u])
{
f[v] = u;
dfs(v);
dp[u][0] += max(dp[v][1], dp[v][0]);
dp[u][1] += dp[v][0];
}
}
}

int main()
{
int i, x, y, pos;
scanf("%d", &n);
memset(head, -1, sizeof(head));
for(i = 1; i <= n; i++) scanf("%d", &val[i]);
for(i = 1; i < n; i++)
{
scanf("%d %d", &x, &y);
add(y, x);
r[x]++;
}
for(i = 1; i <= n; i++)
if(!r[i])
{
pos = i;
break;
}
dfs(pos);
printf("%d", max(dp[pos][0], dp[pos][1]));
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: