首页 > 代码库 > codevs1380 没有上司的舞会

codevs1380 没有上司的舞会

题目描述 Description

      Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。

输入描述 Input Description

第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。

输出描述 Output Description

输出最大的快乐指数。

样例输入 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

数据范围及提示 Data Size & Hint

各个测试点1s

 

一开始想错了,想成了森林转二叉树,后来一想不对,这样的话在递归到某一个节点的时候无法确定自己的上级是否被选择,从而无法确定兄弟节点选不选,因为有自己不选而兄弟节点选这种情况,所以按照最原始的来,对一个节点枚举全部子树,然后判断就行了,没必要复杂化
#include<iostream>#include<cstdio>#include<vector>#define maxn 6005#define inf 1314520using namespace std;int n,happy[maxn],vis[maxn],dp[maxn][2],root;vector<int> l[maxn];void input(){    cin>>n;    for(int i = 1;i <= n;i++){        scanf("%d",&happy[i]);    }    int k,t;    for(int i = 1;i < n;i++){        scanf("%d%d",&t,&k);//k boss        vis[t] = 1;        l[k].push_back(t);            }        for(int i = 1;i <= n;i++){        if(!vis[i]) root = i;        dp[i][0] = dp[i][1] = -inf;    }}void dfs(int now){        dp[now][1] = happy[now];    dp[now][0] = 0;    for(int i = 0;i < l[now].size();i++){        dfs(l[now][i]);            dp[now][1] += dp[l[now][i]][0];        dp[now][0] += max(dp[l[now][i]][1],dp[l[now][i]][0]);    }}int main(){    input();    dfs(root);    cout<<max(dp[root][0],dp[root][1]);    return 0;}

 

codevs1380 没有上司的舞会