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

来源:互联网 发布:人工智能程序原理 编辑:程序博客网 时间:2024/06/08 18:35

题目地址: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;}

大神地址:http://www.cnblogs.com/kuangbin/archive/2012/08/28/2659716.html

0 0