结点选择 (蓝桥杯 树形动态规划)

问题描述

有一棵 n 个节点的树,树上每个节点都有一个正整数权值。如果一个点被选择了,那么在树上和它相邻的点都不能被选择。求选出的点的权值和最大是多少?

输入格式

第一行包含一个整数 n 。

接下来的一行包含 n 个正整数,第 i 个正整数代表点 i 的权值。

接下来一共 n-1 行,每行描述树上的一条边。

输出格式

输出一个整数,代表选出的点的权值和的最大值。

样例输入

5
1 2 3 4 5
1 2
1 3
2 4
2 5

样例输出

12

样例说明

选择3、4、5号点,权值和为 3+4+5 = 12 。

数据规模与约定

对于20%的数据, n <= 20。

对于50%的数据, n <= 1000。

对于100%的数据, n <= 100000。

权值均为不超过1000的正整数。

:dp动态规划好像挺强大的,各种算法好像也挺好玩的,但是实力太差,看别人的代码都要一点一点看分析才能看懂,

什么时候自己才能成为大牛呢(遐想中)

#include<stdio.h>
#include<iostream>
#include<string.h>
#include <vector>
using namespace std;

vector<int>e[100010];
//vector是一种顺序容器,事实上和数组差不多,但它比数组更优越。我个人把它理解为数组队列
//vector可以用下标访问
/*
    构造一棵树出来,遍历,一开始我用的是链式前向星保存数,
    但好像是单向的,没做出来
*/
int pow[100010];//保存每个节点的权值
int vis[100010];//记录每个节点是否走过,走过置1,没走为0
int dp[100010][2];//每个可以选择的点有两种选择
//d[i][0]是不选第i个点
//d[i][1]是选择第i个点 

void dfs(int f)
{
    int size=e[f].size();
    int next;
    dp[f][0]=0;//不选这个点,这个点的就为0
    dp[f][1]=pow[f];
    for(int i=0;i<size;i++)//找所有与f点先连的点
    {
        next=e[f][i];
        if(vis[next]==0)//判断和f先连的这个点是否遍历过
        {
            vis[next]=1;//递归这个点,走过置1
            dfs(next);//递归
            dp[f][1]+=dp[next][0];//如果f点选择,那么和f点先连的点就只能不选
            dp[f][0]+=max(dp[next][1],dp[next][0]);
            //如果f点不选择,那么和f点先连的点有两种选择,dp思想,取最大的
        }
    }

}

int main()
{
    int n,a,b;
    cin>>n;
    memset(vis,0,sizeof(vis));//初始化
    for(int i=1;i<=n;i++)//输入每个点权值
    {
        cin>>a;
        pow[i]=a;
    }
    for(int i=0;i<n-1;i++)
    {
        cin>>a>>b;
        e[a].push_back(b);
        e[b].push_back(a);
        /*
            把终点存进起点的数组里
            把起点存进终点的数组里
        */
    }
    vis[1]=1;
    //从第一个点开始递归
    dfs(1);
    //递归遍历完后,最优解在dp[1][1],dp[1][0]中得出
    printf("%d",max(dp[1][1],dp[1][0]));
    return 0;
}
时间: 2024-11-02 15:53:39

结点选择 (蓝桥杯 树形动态规划)的相关文章

算法笔记_076:蓝桥杯练习 结点选择(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 有一棵 n 个节点的树,树上每个节点都有一个正整数权值.如果一个点被选择了,那么在树上和它相邻的点都不能被选择.求选出的点的权值和最大是多少? 输入格式 第一行包含一个整数 n . 接下来的一行包含 n 个正整数,第 i 个正整数代表点 i 的权值. 接下来一共 n-1 行,每行描述树上的一条边. 输出格式 输出一个整数,代表选出的点的权值和的最大值. 样例输入 51 2 3 4 51 21 32 42 5 样例输出 12 样例说明

树形动态规划练习《蓝桥杯 结点选择》

问题描述 有一棵 n 个节点的树,树上每个节点都有一个正整数权值.如果一个点被选择了,那么在树上和它相邻的点都不能被选择.求选出的点的权值和最大是多少? 输入格式 第一行包含一个整数 n . 接下来的一行包含 n 个正整数,第 i 个正整数代表点 i 的权值. 接下来一共 n-1 行,每行描述树上的一条边. 输出格式 输出一个整数,代表选出的点的权值和的最大值. 样例输入 51 2 3 4 51 21 32 42 5 样例输出 12 样例说明 选择3.4.5号点,权值和为 3+4+5 = 12

蓝桥杯 节点选择 树状动态规划

算法训练 结点选择 时间限制:1.0s   内存限制:256.0MB 锦囊1 使用树型动态规划. 锦囊2 用F[i]表示从子树i中选择结点,且结点i必须被选择的最大值,用G[i]表示从子树i中选择结点,且结点i必须不被选择的最大值. 则F[i]=a[i]+\sum(G[j]),其中a[i]表示结点i的权值,j是i的子结点. G[i]=\sum(max(F[j], G[j])),其中j是i的子结点. 问题描述 有一棵 n 个节点的树,树上每个节点都有一个正整数权值.如果一个点被选择了,那么在树上和

蓝桥杯——说好的进阶之取数博弈游戏(动态规划实现)

今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断. 我们约定: 每个人从盒子中取出的球的数目必须是:1,3,7或者8个. 轮到某一方取球时不能弃权! A先取球,然后双方交替取球,直到取完. 被迫拿到最后一个球的一方为负方(输方) 请编程确定出在双方都不判断失误的情况下,对于特定的初始球数,A是否能赢? 程序运行时,从标准输入获得数据,其格式如下: 先是一个整数n(n<100),表示接下来有n个整数.

算法训练 结点选择 【树形dp】

算法训练 结点选择 时间限制:1.0s   内存限制:256.0MB 问题描述 有一棵 n 个节点的树,树上每个节点都有一个正整数权值.如果一个点被选择了,那么在树上和它相邻的点都不能被选择.求选出的点的权值和最大是多少? 输入格式 第一行包含一个整数 n . 接下来的一行包含 n 个正整数,第 i 个正整数代表点 i 的权值. 接下来一共 n-1 行,每行描述树上的一条边. 输出格式 输出一个整数,代表选出的点的权值和的最大值. 样例输入 5 1 2 3 4 5 1 2 1 3 2 4 2 5

蓝桥杯练习系统题解

转于:http://www.cnblogs.com/cshhr/p/3550014.html 蓝桥杯官网练习系统题解(非VIP) BEGIN-4(Fibonacci数列) 有递推公式,大家都知道用递推公式求,仅仅要记得在递推的时候同一时候取模求好 这里给一份另类代码,用矩阵高速幂求,事实上还有循环节 /* (1 1) * (Fn-1) = ( Fn )//矩阵相乘,将就着看吧 (1 0) (Fn-2) (Fn-1) (1 1) * (1 1) * (Fn-2) = ( Fn ) (1 0) (1

2015年第六届蓝桥杯C/C++B组省赛题目解析

一.奖券数目 有些人很迷信数字,比如带“4”的数字,认为和“死”谐音,就觉得不吉利.虽然这些说法纯属无稽之谈,但有时还要迎合大众的需求.某抽奖活动的奖券号码是5位数(10000-99999),要求其中不要出现带“4”的号码,主办单位请你计算一下,如果任何两张奖券不重号,最多可发出奖券多少张. 请提交该数字(一个整数),不要写任何多余的内容或说明性文字. 分析:直接枚举10000-99999之间的数字,如果带4,直接排除:不带4的,记录一次,直到枚举完后输出. #include <iostream

2015年蓝桥杯省赛B组C/C++(试题+答案)

首先说,这次我是第二次参加蓝桥杯(大学里最后一次),可这次去连个三等都没拿到,有些心灰意冷,比上一次还差, 当时看到成绩出来的时候有些失落,但是跌倒了,再站起来继续跑就可以了.可能是状态不好吧,纯属自我安慰. 接下来我把今年的题目又重新做了一遍,写下了这篇博客,如果也有需要探讨答案的,希望可以有帮助. 第一题: 第1题:统计不含4的数字 题目大意 统计10000至99999中,不包含4的数值个数. 解题分析: 第一种解法: 数学方法,这种是在网上看到的一种解法: 最高位除了0.4不能使用,其余8

第六届蓝桥杯本科B组C++省赛题解

比赛结束已经一星期了,成绩也出来了,江苏非211组的省前十,但是深感自己还是有太多的不足.绝对不能以自己还只是大一为借口,acm这条路还长的很. 目测得了95分(满分150),第一题错了,代码填空第一题错了,倒数第二题扣了一点分,最后一道大题全错. 之所以会这么晚来发这道题解,是因为深感自己不足,倒数第二题之所以没有做出来,是因为自己居然不会用[矩阵快速幂].因此,现学现用以自省. 关于题目:所有填空题都可以纯暴力,只要会回溯剪枝法对于蓝桥杯已经足够了.大题目难度一年比一年高 第一题 结果填空