没有上司的舞会

在这里插入图片描述
输入:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0

输出:
5

备注:
1 ≤ N ≤ 6000
-128 ≤ Hi ≤ 127

思路: 核心:树形dp
最大独立子集
确定状态转移方程
每个结点分选和不选的情况
假设x为结点
情况一 x选,儿子都不选
f[x][1]=∑f[son][o]

情况二 x不选,儿子选和不选都行,选大的
f[x][0]=∑max( f[son][0],f[son][1] )

//dp
//f[x][1]选=和f[son]][0]
//f[x][0]不选=和max( f[son][0],f[son][1] )
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int  ans=0;
const int N=6000+10;
int tot=0;
int happy[N];
int head[N];
int f[N][2];
struct node
{
    int t,next;
}edge[N];
void addedge(int x,int y)
{
    edge[++tot].t=y;
    edge[tot].next=head[x];
    head[x]=tot;
}
void dfs(int x,int fa)
{
    for(int i=head[x] ;i!=-1 ;i=edge[i].next)
    {
        int y=edge[i].t;
        if( y==fa ) continue;
        dfs(y,x);
        f[x][1]+=f[y][0];
        f[x][0]+=max(f[y][1], f[y][0]);
    }
    ans=max(ans,f[x][1]);
    ans=max(ans,f[x][0]);
}
int main()
{
    int n;
    cin>>n;
    for(int i=1 ;i<=n ;i++)
       {cin>>f[i][1];head[i]=-1;}
    while(1)
    {
        int x,y;
        cin>>x>>y;
        if( x==0 && y==0 ) break;
        addedge(x,y);
        addedge(y,x);
    }
    dfs(1,0);
    cout<<ans<<endl;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值