洛谷-P1352 没有上司的舞会

题意:

某大学有1-n个职员

他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。

现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数 ,但是呢,如果某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。

所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

链接:https://www.luogu.com.cn/problem/P1352

输入:

输入的第一行是一个整数 n

第二行到第n+1行,每行一个数代表快乐值
接下来n行每行两个数x,y,代表y是x的上司
输出:
最大的快乐值
思路:
树形DP,设dp[i][0]代表这个职工去了,dp[i][1]代表这个职工没去,v代表该职工的手下
如果该职工去了那么他的手下就不能再去,所以得到转移方程dp[i][0]=dp[i][0]+dp[v][1]
如果该职工没去他们他的手下就可以去,所以要考虑他的手下去或不去的两种情况,
所以得到dp[i][1]=dp[i][1]+max(dp[v][0],dp[v][1]);
在回溯的时候由叶子节点向根节点更新
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5+ 5;
const int INF = 1e16;
typedef long long ll;
int a[MAXN],dp[7000][2],fa[MAXN];
vector<int>v[MAXN];
void dfs(int u)
{
    for(int i=0; i<v[u].size(); i++)
    {
        int nxt=v[u][i];
        dfs(nxt);
        dp[u][0]+=dp[nxt][1];
        dp[u][1]+=max(dp[nxt][0],dp[nxt][1]);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>dp[i][0];
    }
    for(int i=1;i<=n-1;i++)
    {
        int x,y;
        cin>>x>>y;
        if((!x)&&(!y))
            break;
        v[y].push_back(x);
        fa[x]=1;
    }
    int index=0;
    for(int i=1; i<=n; i++)
    {
        if(!fa[i])
        {
            index=i;
            break;
        }
    }
    dfs(index);
    cout<<max(dp[index][0],dp[index][1]);
}
原文地址:https://www.cnblogs.com/ljxdtc666/p/12491826.html