最大利润(树型动态规划)

题目描述

【题目描述】

  政府邀请了你在火车站开饭店,但不允许同时在两个相连接的火车站开。任意两个火车站有且只有一条路径,每个火车站最多有50个和它相连接的火车站。告诉你每个火车站的利润,问你可以获得的最大利润为多少?例如下图是火车站网络:

  最佳投资方案是在1,2,5,6这 4个火车站开饭店可以获得利润为90。

输入输出格式

输入格式:

  第一行输入整数N(≤100000),表示有N个火车站,分别用1,2,…,N来编号。接下来 N 行,每行一个整数表示每个站点的利润,接下来 N 一 1 行描述火车站网络,每行两个整数,表示相连接的两个站点。

输出格式:

  输出一个整数表示可以获得的最大利润。

解题思路:

这是一道树形动态规划,dp[i][0]表示以i为根时,不选i的最大值,dp[i][1]为选i时的最大值;从根开始递归每一层,当选i时,不选它的子节点,则d[i][1]=d[i][1]+d[j][0];不选i时,可选可不选子节点(选最大),则d[i][0]=d[i][0]+max(d[j][0],d[j][1]),其中j为i的子节点。最终输出max(dp[rood][0],dp[rood][1]);

注意,数据量大,邻接表要把二维转一维

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
    int from,to,next,head;
}q[1100000];
int i,j,n,x,y,w[1100000],vis[1100000],d[1100000][2],s=0;
void dp(int r)
{
    if(vis[r]) return;
    else vis[r]=1;
    int k,j;
    k=q[r].head;
    while(k!=0)
    {
        j=q[k].to;
        if(!d[j][0]&&!d[j][1])
        {
            dp(j);
            d[r][0]+=max(d[j][0],d[j][1]);
            d[r][1]+=d[j][0];
        }
        k=q[k].next;
    }
    d[r][1]+=w[r];
}
int main()
{
    cin>>n;
    for(i=1;i<=n;i++) cin>>w[i];
    for(i=1;i<n;i++)
    {
        cin>>x>>y;
        q[++s].from=x;
        q[s].to=y;
        q[s].next=q[x].head;
        q[x].head=s;
        q[++s].from=y;
        q[s].to=x;
        q[s].next=q[y].head;
        q[y].head=s;
    }
    dp(1);
    cout<<max(d[1][0],d[1][1]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值