题目描述
某公司要举办一次晚会,
但是为了使得晚会的气氛更加活跃,
每个参加晚会的人都不希望在晚会中见到他的上司,
要不然他们会很扫兴。
现在已知每个人的活跃指数和上司关系(当然不可能存在环),
求邀请哪些人来能使得晚会的总活跃指数最大。
树形动规
利
用
链
式
储
存
结
构
。
对
于
每
一
个
顶
点
,
开
一
条
链
,
依
次
存
储
以
该
点
为
起
点
的
边
。
利用链式储存结构。对于每一个顶点,开一条链,依次存储以该点为起点的边。
利用链式储存结构。对于每一个顶点,开一条链,依次存储以该点为起点的边。
下
面
的
代
码
用
e
数
组
储
存
边
的
信
息
,
h
e
a
d
[
i
]
储
存
i
这
个
顶
点
对
应
的
链
的
起
始
位
置
。
下面的代码用e数组储存边的信息,head[i]储存i这个顶点对应的链的起始位置。
下面的代码用e数组储存边的信息,head[i]储存i这个顶点对应的链的起始位置。
通
时
e
中
的
n
e
x
t
域
使
所
有
起
始
点
为
i
的
边
连
成
一
条
链
。
通时e中的 next域使所有起始点为i的边连成一条链。
通时e中的next域使所有起始点为i的边连成一条链。
从
根
节
点
开
始
递
归
!
从根节点开始递归!
从根节点开始递归!
代码:
#include<iostream>
#include<cstdio>
using namespace std;
struct NOTE
{
int x,y,next;
}e[18926];
int head[10001],f[10001][2],h[10001],boss[10001],x,y,n,tot;
void add(int x,int y) //建立链表
{
e[++tot].x=x;
e[tot].y=y;
e[tot].next=head[x];
head[x]=tot;
}
void dp(int now) //递归+dp
{
f[now][1]=h[now];
for(int i=head[now]; i!=0; i=e[i].next)
{
dp(e[i].y);
f[now][1]=f[now][1]+f[e[i].y][0];
f[now][0]=max(f[e[i].y][1],f[e[i].y][0])+f[now][0];
}
}
int main()
{
int k;
cin>>n;
for(int i=1; i<=n; i++)
cin>>h[i];
cin>>x>>y;
while(x+y!=0)
{
add(y,x);
boss[x]=1;
cin>>x>>y;
}
for(int i=1; i<=n; i++)
if(boss[i]==0)
{
k=i;
break;
}
dp(k);
cout<<max(f[k][0],f[k][1]);
return 0;
}
老师真好~~~