【u228】圣诞树

【问题描述】
圣诞特别礼物挂在一棵圣诞树上,这棵树有n层,每层有一件礼物,每件礼物都有一个价值,有的礼物还有一些连结线,与下层的礼物相连,领取礼物的规则如下:任选一件礼物,它的下面如果有连结线,则可以继续取它连结的礼物,以此类推,直至取到没有连结线的礼物才结束,你如果是第一个去取,怎样取才能获得最大的价值呢?请你编一程序解决这一问题。
【输入文件】
输入文件tree.in的第一行只有一个数据n(n<=100),表示有n层礼物,以下有n行数据,分别表示第1-n层礼物的状态,每行至少由一个数据构成,且第一个数据表示该礼物的价值,后面的数据表示它与哪些层的礼物相连,如果每行只有一个数据则说明这层礼物没有与下层礼物相连,每个数的大小均不超过10000。
【输出文件】
输出文件tree.out也只有一个数,表示获得的取大价值。
【输入样例】
3
12 2 3
20
30
【输出样例】
42
【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u228

【题解】

设f[x]表示选第x层的礼物能够获得的最大价值;
f[x] = a[x];
f[x] = max(f[x],f[x]+max(f[x的儿子节点]);
最后1..n取最大的f值;
一棵树可能有多个根;
之前算过的f值就不要重复算了.
一行里面有未知个数的数字的;
可以用cin.peek()函数来判断是不是读到了行末

【完整代码】

#include <cstdio>
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int MAXN = 110;

int n;
int a[MAXN],f[MAXN];
vector <int> g[MAXN];
bool bo[MAXN];

void dfs(int x)
{
    f[x] = a[x];
    bo[x] = true;
    int len = g[x].size(),temp = -21e8;
    rep1(i,0,len-1)
    {
        int y = g[x][i];
        if (!bo[y])
            dfs(y);
        temp = max(temp,f[y]);
    }
    if (temp>0)
        f[x]+=temp;
}

int main()
{
    //freopen("F:\rush.txt","r",stdin);
    cin >> n;
    char t = getchar();//把换行符给读了
    rep1(i,1,n)
    {
        int x;
        rei(a[i]);
        while (cin.peek()!=EOF)
        {
            if (isdigit(cin.peek()))
            {
                cin >> x;
                g[i].pb(x);
            }
            if (cin.peek()=='
')
                break;
            cin.ignore();
        }
        t = getchar();
    }
    rep1(i,1,n)
        if (!bo[i])
        {
            dfs(i);
        }
    int ans = f[1];
    rep1(i,2,n)
        ans = max(ans,f[i]);
    printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626653.html