Ural大学有N名职员,编号为1~N。
他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。
每个职员有一个快乐指数,用整数 Hi 给出,其中 1≤i≤N,1≤i≤N1\leq i\leq N,1\leq i\leq N1≤i≤N,1≤i≤N。
现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。
输入
第一行一个整数N。
接下来N行,第 i 行表示 i 号职员的快乐指数Hi。
接下来N-1行,每行输入一对整数L, K,表示K是L的直接上司。
最后一行输入0,0。
输出
输出最大的快乐指数。
样例输入
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
样例输出
5
提示
1≤N≤6000, −128\leq H_i\leq 127−128≤Hi≤127
代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#define N 7000
using namespace std;
int dp[N][2],h[N];//dp[i][1]表示取点,[0]表示不取
int judge[N];//判断是不是根节点
vector<int> son[N];//N个父节点,每个容器里存下自己的儿子
void dfs(int u)
{
dp[u][0]=0;
dp[u][1]=h[u];//存为这个点的价值,反正过程是累加
for(int i=0;i<son[u].size();i++)
{//儿子是从i=0开始弹入的
int v=son[u][i];
dfs(v);//深搜子树,//用搜出来的结果开始找最优解
dp[u][1]+=dp[v][0];//取的话累加子树不取的情况
dp[u][0]+=max(dp[v][1],dp[v][0]);//不去的话找到子树取或不取的最优解
}
return;
}
int main()
{
int n,m,l,k;
cin>>n;
for(int i=1;i<=n;i++)
cin>>h[i];
for(int i=1;i<n;i++){
cin>>l>>k;
son[k].push_back(l);
judge[l]=1;//不是祖先,最后只有祖先才不为1
}
int start=0;
for(int i=1;i<=n;i++){//找祖先,从祖先开始深搜
if(!judge[i])//是根节点的话
{
start=i;
break;
}
}
dfs(start);
cout<<max(dp[start][0],dp[start][1])<<endl;
return 0;
}
这是一个关于树形结构的问题,给定一个以校长为根的树形组织,每个职员有快乐指数,宴会中不能有职员与他的直接上司。目标是找出能参加宴会的职员组合,使快乐指数之和最大。代码通过深度优先搜索遍历树,计算每个节点取或不取的最大快乐指数,最终找到最优解。
2660

被折叠的 条评论
为什么被折叠?



