您的位置:首页 > 其它

dp优化专辑 C - Anniversary party [树形dp]

2011-08-17 08:14 579 查看
看到了一样的题,直接把POJ上的替贴了进来,发现TLE了





HDU上的测试数也太多了吧,分析了下POJ的代码,发现时间复杂度过高(有点暴力倾向),只要修改代码了。。。

题意:

某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大。

思路:

任何一个点的取舍可以看作一种决策,那么状态就是在某个点取的时候或者不取的时候,以他为根的子树能有的最大活跃总值。分别可以用f[i,1]和f[i,0]表示第i个人来和不来直接记录在结构体中~

#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<map>
using namespace std;
#define N 6001
struct node
{
int father;
int child;
int brother;
int attend;//参加了
int notattend;//没有参加
void init()
{
father=0;
child=0;
brother=0;
notattend=0;
}
} p
;
void dfs(int start)
{
int child;
child=p[start].child;
while(child)
{
dfs(child);
p[start].attend+=p[child].notattend;
if(p[child].attend>p[child].notattend)
p[start].notattend+=p[child].attend;
else
p[start].notattend+=p[child].notattend;
child=p[child].brother;//兄弟结点
}
}
int main()
{
int n,root;
while(scanf("%d",&n)!=EOF)
{
for(int i=1; i<=n; i++)
{
p[i].init();
scanf("%d",&p[i].attend);
}
int a,b;
while(scanf("%d%d",&a,&b),a||b)
{
root=b;
p[a].father=b;
p[a].brother=p[b].child;
p[b].child=a;
}
while(p[root].father)//寻找父节点
root=p[root].father;
dfs(root);
printf("%d\n",p[root].attend>p[root].notattend?p[root].attend:p[root].notattend);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: