您的位置:首页 > 其它

hdu 1520 Anniversary party(树形dp)

2014-09-16 14:25 274 查看
题目链接

题意:

输入一个N,代表树的结点个数,接下来N行代表1到N节点的欢乐值,之后的若干行输入为L和K,表示L的父节点为K,求的是该树最大的欢乐值为多少,需注意的是父子节点不能同时出现。

分析:

用d[i][0] 表示节点i 不出现的最大欢乐值,d[i][0]表示节点i 出现的最大欢乐值。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#define LL __int64
const int maxn = 6000+10;
using namespace std;
int a[maxn], head[maxn], d[maxn][2], ans, vis[maxn], t;
struct node
{
int u, v, to;
} e[2*maxn];
void add(int u, int v)
{
e[t].u = u;
e[t].v = v;
e[t].to = head[u];
head[u] = t++;
}
void dfs(int u)
{
int i, v;

vis[u] = 1;
for(i = head[u]; i != -1; i = e[i].to)
{
v = e[i].v;
if(vis[v]) continue;
dfs(v);
d[u][1] += d[v][0];
d[u][0] += max(d[v][0], d[v][1]);
}
}

int main()
{
int i, n, l, k;
while(~scanf("%d", &n))
{
for(i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
d[i][0] = 0;
d[i][1] = a[i];
}
t = 0;
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));

while(~scanf("%d%d", &l, &k))
{
if(l==0 && k==0) break;
add(k, l);
add(l, k);
}
dfs(1);
ans = max(d[1][0], d[1][1]);
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: