0
点赞
收藏
分享

微信扫一扫

HDU 1520 Anniversary party(有向边树形DP)

犹大之窗 2022-08-04 阅读 24


题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1520

题意:题目是说有N个人参加party,每个人有一个rating值(可以理解为权值)和一个up(上司的编号),为了保证party的趣味性,每一个人不可以和他的直接上司都参加,问最后的rating和最大

思路:和数塔问题查不到,数塔问题真正理解了,看看代码就能很快理解,参考的大神的代码

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

typedef long long ll;
using namespace std;
const int maxn = 6010;

vector<int> vec[maxn];//这里相当于一个二维数组,只所以用vector是因为可以迅速知道他的子节点的个数
int head[maxn];//标记父节点
int value[maxn];//标记他本省的值
int dp[maxn][2];

void dfs(int root)
{
int len = vec[root].size();
dp[root][1] = value[root];//上级要参加初始化一下
for(int i=0; i<len; i++)
{
dfs(vec[root][i]);//求每个子节点的最大值
}
for(int i=0; i<len; i++)
{
dp[root][0] += max(dp[vec[root][i]][0],dp[vec[root][i]][1]);//每个子节点都取最大值加起来
dp[root][1] += dp[vec[root][i]][0];//父节点参加,子节点就都不能参加了
}
}

int main()
{
int n;
while(scanf("%d",&n) != EOF)
{
memset(head,-1,sizeof(head));
memset(dp,0,sizeof(dp));
for(int i=1; i<=n; i++)
{
scanf("%d",&value[i]);
vec[i].clear();//每次把向量容器清空
}
int a,b;
while(scanf("%d%d",&a,&b))
{
if(a + b == 0)
break;
head[a] = b;
vec[b].push_back(a);
}
a = 1;
while(head[a] != -1)//找根节点
a = head[a];
dfs(a);
printf("%d\n",max(dp[a][1],dp[a][0]));
}
return 0;
}


举报

相关推荐

0 条评论