最大独立集

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
Ural大学有N名职员,编号为1~N。
他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。
每个职员有一个快乐指数,用整数 HiHi 给出,其中 1≤i≤N,1≤i≤N1\leq i\leq N,1\leq i\leq N1≤i≤N,1≤i≤N。
现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。

题解:本题的实质就是求最大独立集的权值之和的最大值

确定状态:f[i][0]表示i这个点不选时i点及其子树的最大权值

f[i][1]表示i这个点选中时i点及其子树的最大权值

状态转移方程:

f[i][0]=\sumMAX(f[j][0],f[j][1])j为i的子结点

                f[i][1]=h[i]+\sumf[j][0]

边界条件:

f[i][0]=0                f[i][1]=h[i]

结果就是max(f[root][0],f[root][1])

那么如何找出这个根结点的值呢?我们发现一颗n个结点的树有n-1条边,这n-1个父子关系中没有出现过作为子节点的点就是根结点,具体实现参照代码

#include<bits/stdc++.h>
using namespace std;
int n;
int h[6200];
vector<int>son[6100];
int f[6100][2];
void dfs(int i)
{
    f[i][0]=0;
    f[i][1]=h[i];
    for(int x=0;x<son[i].size();x++)
    {
        int j=son[i][x];
        dfs(j);
        f[i][0]+=max(f[j][0],f[j][1]);
        f[i][1]+=f[j][0];
    }
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>h[i];
    }    
    int root=n*(n+1)/2;
    for(int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        son[y].push_back(x);
        root-=x;
    }
    dfs(root);//从根开始搜
    cout<<max(f[root][0],f[root][1]);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流浪小林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值