【u228】圣诞树

来源:互联网 发布:张予曦淘宝店换了吗 编辑:程序博客网 时间:2024/04/28 19:25

【问题描述】
圣诞特别礼物挂在一棵圣诞树上,这棵树有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()=='\n')                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\n",ans);    return 0;}
0 0