p1352 没有上司的舞会

传送门

题目

某大学有N个职员,编号为1~N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

输入格式:

第一行一个整数N。(1<=N<=6000)

接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)

接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。

最后一行输入0 0

输出格式:

输出最大的快乐指数。

分析

一道经典的树型dp模板题,dp[i][0/1]表示第i个节点选还是不选,因为如果一个点选了它的儿子都不能选,一个点如果不选它的儿子既可以选也可以不选,所以我们不难得出代码中的转移方程

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
using namespace std;
int n,m;
vector<int>v[6010];
int dp[6500][3];
int val[6500];
void dfs(int x,int fa){
    int i;
    dp[x][1]=val[x];
    if(v[x].size()==0)return;
    for(i=0;i<v[x].size();i++)
       if(v[x][i]!=fa){
            dfs(v[x][i],x);
            dp[x][0]+=max(0,max(dp[v[x][i]][0],dp[v[x][i]][1]));
            dp[x][1]+=max(0,dp[v[x][0]][0]);
       }
    return;
}
int main(){
    int i,j,k;
    cin>>n;
    for(i=1;i<=n;i++)
       cin>>val[i];
    for(i=1;i<n;i++){
        int x,y;
        cin>>x>>y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    cin>>i>>j;
    dfs(1,0);
    cout<<max(dp[1][0],dp[1][1])<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/yzxverygood/p/9039536.html