[CF486D]有效集合-树形dp
Problem 有效集合
题目大意
给出一棵树,求出这棵树的不同联通子节点集合的数量,这些集合必须满足最大权值点减最小权值点小于等于d。
Solution
再一次树d乱搞。
因为数据范围贼小,所以我们对于每一个点为根的情况进行一次dfs.
对于以节点root为根的情况,我们认为root是最小值。
对于root的某一棵子树,其需要算的情况一定包含root,否则前面已经算过了。
于是我们就对这个root进行dfs。dfs过程中,我们始终保证root为最小值,不遍历大于它的点。
因为有了这个性质,我们只要不走加起来大于d的点,接下来所有的点都不属于被计算范围内,可以不走。
在这个以root为根的树中,现在我们遍历到u,选中它的一颗子树v。
对于这一串东西上,我们每次可以选择以前已遍历过的子树中选择某些点,再从v该棵子树下选择某些点组成新情况。
我们增加的情况是已经遍历过的子树答案*(该子树被遍历到的子树总答案+1)
加一是因为空集也算是一种情况。
也就是f[u]*=f[v]+1;
对于每个叶子结点,我们只需要将f设为1即可。
dfs完以后,我们将以每个点为根(最小值)的情况进行累加。
于是最终的ans便是答案。
需要注意的是,这一道题MOD1000000007
所以f数组、ans变量需要long long类型
而我一直爆炸,因为没注意到,dfs函数也要为long long类型。
所以请注意这个问题。
AC Code
#include <iostream>
#include <cstdio>
#include <cstring>
#define MOD 1000000007
using namespace std;
struct node{
int to,next;
}e[];
int d,n,u,v,h[],a[],tot=;
long long f[],ans=;
void add(int u,int v){
e[++tot].to=u;e[tot].next=h[v];h[v]=tot;
e[++tot].to=v;e[tot].next=h[u];h[u]=tot;
}
long long dfs(int x,int last,int root){
long long ans=;
f[x]=;
for(int i=h[x];~i;i=e[i].next){
if(last!=e[i].to&&(a[e[i].to]>a[root]||(a[e[i].to]==a[root]&&root>e[i].to))
&&a[e[i].to]-a[root]<=d){
ans=(ans*(dfs(e[i].to,x,root)+)%MOD)%MOD;
}
}
return ans;
}
int main(){
// freopen("cf486d.in","r",stdin);
memset(h,-,sizeof(h));
scanf("%d%d",&d,&n);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
}
for(int i=;i<=n;i++)ans+=dfs(i,,i);
printf("%lld",ans%MOD);
}
[CF486D]有效集合-树形dp的更多相关文章
- BZOJ 4455: [Zjoi2016]小星星 [容斥原理 树形DP]
4455: [Zjoi2016]小星星 题意:一个图删掉一些边形成一棵树,告诉你图和树的样子,求让图上的点和树上的点对应起来有多少方案 看了很多题解又想了一段时间,感觉题解都没有很深入,现在大致有了自 ...
- 树形DP题目集合
[树形DP](https://cn.vjudge.net/contest/123963#overview) #include<cstdio> #include<string> ...
- CF 486D vailid set 树形DP
As you know, an undirected connected graph with n nodes and n - 1 edges is called a tree. You are gi ...
- POJ 3342 (树形DP)
题意 :给出一些上下级关系,要求i和i的直接上级不能同时出现,现在选出一些人构成一个集合,问你这个集合里面的最大人数是都少,同时给出这个最大的人数的集合是否唯一. 思路:树形DP,dp[i][0],表 ...
- 『没有上司的舞会 树形DP』
树形DP入门 有些时候,我们需要在树形结构上进行动态规划来求解最优解. 例如,给定一颗\(N\)个节点的树(通常是无根树,即有\(N-1\)条无向边),我们可以选择任意节点作为根节点从而定义出每一颗子 ...
- 洛谷P1040 加分二叉树(树形dp)
加分二叉树 时间限制: 1 Sec 内存限制: 125 MB提交: 11 解决: 7 题目描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,...,n),其中数字1,2,3,...,n ...
- Codeforces 1097G Vladislav and a Great Legend [树形DP,斯特林数]
洛谷 Codeforces 这题真是妙的很. 通过看题解,终于知道了\(\sum_n f(n)^k\)这种东西怎么算. update:经过思考,我对这题有了更深的理解,现将更新内容放在原题解下方. ...
- 树形动态规划(树形DP)入门问题—初探 & 训练
树形DP入门 poj 2342 Anniversary party 先来个题入门一下~ 题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上 ...
- BZOJ4455 ZJOI2016小星星(容斥原理+树形dp)
相当于给树上的每个点分配一个编号使父亲和儿子间都有连边. 于是可以考虑树形dp:设f[i][j][k]为i号点的编号为j,其子树中编号集合为k的方案数.转移显然.然而复杂度3n·n3左右,具体我也不知 ...
随机推荐
- Python可视化:Seaborn库热力图使用进阶
前言 在日常工作中,经常可以见到各种各种精美的热力图,热力图的应用非常广泛,下面一起来学习下Python的Seaborn库中热力图(heatmap)如何来进行使用. 本次运行的环境为: windows ...
- 如何同时完成多个ajax之后再执行某个方法 ? 使用$.when().done();
jQuery中的$.when()方法比较复杂,这里不作全面讲解,只写一个同时完成多个ajax请求后执行操作的方法. 有时候我们需要等待多个ajax执行完以后,再执行某个操作. 写法如下: $.when ...
- servlet与Javabean之间的区别
在JSP中调用JAVA类和使用JavaBean有什么区别? 可以像使用一般的类一样使用JavaBean,Bean只是一种特殊的类.特殊在可以通过<jsp:useBean/>调用JavaBe ...
- 编写高质量代码改善程序的157个建议:使用Dynamic来简化反射的实现
最近有时间看点书了,把157个建议在重新看一遍,代码都调试一遍.当我看到第15个建议的时候有些出入,就记录下来,欢迎大家来探讨. 第十五条建议是,使用dynamic简化反射的使用,没有说明具体的条件. ...
- Javascript数组操作详细解答
数组push()方法向数组尾部追加新元素,返回值为新数组的长度;括号里面带新追加的元素pop()方法从数组尾部移除一个元素,返回值为移除的元素括号里面不能带参数 shift()方法从数组头部移除一个元 ...
- 带着问题写React Native原生控件--Android视频直播控件
最近在做的采用React Native项目有一个需求,视频直播与直播流播放同一个布局中,带着问题去思考如何实现,能更容易找到问题关键点,下面分析这个控件解决方法: 现在条件:视频播放控件(开源的ijk ...
- 编写自己的Nmap(NSE)脚本
编写自己的Nmap脚本 一.介绍 在上一篇文章Nmap脚本引擎原理中我们介绍了基本的NSE知识,这篇文章介绍如何基于Nmap框架编写简单的NSE脚本文件,下一篇文章,Nmap脚本文件分析(AMQP协议 ...
- Java IO学习笔记四
内存操作流 之前的所有的流操作都是针对文件的,但是有时候只是想要实现数据间转换,此时如果我们想要创建一个文件然后再删除文件,那样显得有点麻烦,因此此时的内存操作流就显得很适合这类的操作,因为它只是在内 ...
- Docker Machine 详解
笔者在<Docker Machine 简介>一文中简单介绍了 Docker Machine 及其基本用法,但是忽略的细节实在是太多了.比如 Docker 与 Docker Machine ...
- qt中setStyleSheet导致的内存泄漏
原始日期: 2017-01-05 19:31 现象:程序运行至某一个界面下,内存出现缓慢持续的占用内存增长 原因:经过排查,确定是在事件派发的槽函数中频繁重复调用setStyleSheet导致的 ...