hdu 1520 2011.2.26

Hdu 1520 Anniversary party

 

【关键字】

树形动态规划

 

【摘要】

要求从一棵带权树中选择若干点,在选择父亲节点就不能选儿子几点的前提下,权值最大。

 

【正文】

1.题目描述

Anniversary party

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 685    Accepted Submission(s): 285

 

Problem Description

There is going to be a party to celebratethe 80-th Anniversary of the Ural State University. The University has ahierarchical structure of employees. It means that the supervisor relationforms a tree rooted at the rector V. E. Tretyakov. In order to make the partyfunny for every one, the rector does not want both an employee and his or herimmediate supervisor to be present. The personnel office has evaluatedconviviality of each employee, so everyone has some number (rating) attached tohim or her. Your task is to make a list of guests with the maximal possible sumof guests' conviviality ratings.

 

Input

Employees are numbered from 1 to N. A firstline of input contains a number N. 1 <= N <= 6 000. Each of thesubsequent N lines contains the conviviality rating of the correspondingemployee. Conviviality rating is an integer number in a range from -128 to 127.After that go T lines that describe a supervisor relation tree. Each line ofthe tree specification has the form:

L K

It means that the K-th employee is animmediate supervisor of the L-th employee. Input is ended with the line

0 0

 

Output

Output should contain the maximal sum ofguests' ratings.

 

Sample Input

7

1

1

1

1

1

1

1

1 3

2 3

6 4

7 4

4 5

3 5

0 0

 

Sample Output

5

 

Source

Ural State University Internal ContestOctober'2000 Students Session

 

Recommend

linle

2.算法分析

树形动态规划

Tree[r].yes 以r节点为根,包含i节点的最大权值;

Tree[r].no  以r节点为根,不包含i节点的最大权值;

对于节点Tree[r] 的每个孩子,tree[u]

Tree[r].no=∑max(tree[u].yes,tree[u].no);

Tree[r].yes=tree[r].value+∑ tree[u].no;

最后结果 max(tree[root].yes,tree[root].no);

3.源码


#include <iostream>
#include <vector>

using namespace std;

#define MAXN 6000+10

struct node0
{
    int yes,no;
    int value;
    vector<int> son;
    bool visit;
    bool root;
}tree[MAXN];

int n,root;
void init()
{
    for(int i=1;i<=n;i++)
    {
        cin>>tree[i].value;
        tree[i].son.clear();
        tree[i].yes=0;
        tree[i].no=0;
        tree[i].visit=false;
        tree[i].root=true;
    }
    int l,k;
    while (cin>>l>>k)
    {
        if ((l==0)&&(k==0))
            break;
        tree[k].son.push_back(l);
        tree[l].root=false;
    }
}

int max(int x,int y)
{
    if (x<y) return y;
    else return x;
}

void dfs(int r)
{
    if (tree[r].visit) return ;
    tree[r].visit=true;
    int ans=0,ans1=0;
    for(int i=0;i<tree[r].son.size();i++)
    {
        int u=tree[r].son[i];
        if (tree[u].visit==false)
        {
            dfs(u);
            ans+=max(tree[u].yes,tree[u].no);
            ans1+=tree[u].no;
        }
    }
    tree[r].yes=ans1+tree[r].value;
    tree[r].no=ans;
}

void doit()
{
    for(int i=1;i<=n;i++)
    {
        if (tree[i].root)
        {
        //    cout<<"i"<<i<<endl;
            dfs(i);
            cout<<max(tree[i].yes,tree[i].no)<<endl;
            break;
        }
    }
}

int main()
{
    while(cin>>n)
    {
        init();
        doit();
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值