题目链接:http://codeforces.com/problemset/problem/486/D

题意:

  给你一棵树,n个节点,每个节点的点权为a[i]。

  问你有多少个连通子图,使得子图中的max(a[i]) - min(a[i]) <= d。

  ps.连通子图的定义:

    如果一个点集V为一个连通子图,则对于任意两点a,b∈V,有a到b路径上的所有点u∈V。

题解:

  因为要保证max(a[i]) - min(a[i]) <= d,所以可以人为地选出一个点rt作为点权最大的点。

  这样在求以rt为最大点的连通子图个数时,只用考虑点权不超过a[rt]的点。

  然而如果有两个点i,j的点权相同,分别以i,j作为最大点的两堆子图中会有重复。

  所以可以定义一下:当以rt作为最大点时,所有点权与a[rt]相等的点,它们的节点编号id[i]必须大于id[rt]。

  这样就能避免重复了。

  所以最终答案 = ∑(以i为最大点的连通子图个数)

  求以i为最大点的连通子图个数,只需一遍O(n)的dp就行。

  注意,当前这是一棵无根树。以下所说的“i的子树”意思是:从i出发往叶子方向的那一堆点。

  假设当前以rt作为最大点。  

  则加入连通子图的点i必须满足:

    (1)a[rt]-a[i]<=d(保证满足题目条件)

    (2)a[i]<=a[rt](保证a[rt]为最大点)

    (3)如果a[i]==a[rt] && i!=rt,则要满足rt<i(避免重复计数)

  表示状态:

    dp[i] = numbers

    表示节点i肯定要选,i的子树所构成的合法连通子图个数

  找出答案:

    每次ans += dp[rt]

  如何转移:

    dp[i] = ∏ (dp[son]+1)

  边界条件:

    对于叶子结点leaf: dp[leaf] = 1

  总复杂度O(n^2)。

AC Code:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#define MAX_N 2005
#define MOD 1000000007 using namespace std; int n,d;
int a[MAX_N];
vector<int> edge[MAX_N]; void read()
{
cin>>d>>n;
for(int i=;i<=n;i++) cin>>a[i];
int x,y;
for(int i=;i<n;i++)
{
cin>>x>>y;
edge[x].push_back(y);
edge[y].push_back(x);
}
} long long dfs(int now,int p,int rt,int mx)
{
if(mx-a[now]>d || a[now]>mx || (a[now]==mx && p!=- && now<rt)) return ;
long long res=;
for(int i=;i<edge[now].size();i++)
{
int temp=edge[now][i];
if(temp!=p) res=res*(dfs(temp,now,rt,mx)+)%MOD;
}
return res;
} void work()
{
long long ans=;
for(int i=;i<=n;i++) ans=(ans+dfs(i,-,i,a[i]))%MOD;
cout<<ans<<endl;
} int main()
{
read();
work();
}

Codeforces 486D Valid Sets:Tree dp【n遍O(n)的dp】的更多相关文章

  1. Codeforces 486D Valid Sets (树型DP)

    题目链接 Valid Sets 题目要求我们在一棵树上计符合条件的连通块的个数. 满足该连通块内,点的权值极差小于等于d 树的点数满足 n <= 2000 首先我们先不管这个限制条件,也就是先考 ...

  2. Codeforces 486D. Valid Sets

    D. Valid Sets time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  3. Codeforces Round #277 (Div. 2) D. Valid Sets (DP DFS 思维)

    D. Valid Sets time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  4. Codeforces Round #277 (Div. 2) D. Valid Sets DP

    D. Valid Sets   As you know, an undirected connected graph with n nodes and n - 1 edges is called a  ...

  5. codeforces 486 D. Valid Sets(树形dp)

    题目链接:http://codeforces.com/contest/486/problem/D 题意:给出n个点,还有n-1条边的信息,问这些点共能构成几棵满足要求的树,构成树的条件是. 1)首先这 ...

  6. Codeforces Round #277 (Div. 2) D. Valid Sets 暴力

    D. Valid Sets Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/486/problem ...

  7. Codeforces 461B Appleman and Tree(木dp)

    题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...

  8. Codeforces 442D Adam and Tree dp (看题解)

    Adam and Tree 感觉非常巧妙的一题.. 如果对于一个已经建立完成的树, 那么我们可以用dp[ i ]表示染完 i 这棵子树, 并给从fa[ i ] -> i的条边也染色的最少颜色数. ...

  9. Codeforces 280C Game on tree【概率DP】

    Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...

随机推荐

  1. Amzaon EC2虚拟化技术演进:从 Xen 到 Nitro

      今年2月,由光环新网运营的 AWS 中国(北京)区域和由西云数据运营的 AWS 中国 (宁夏)区域发布新的实例类型,新的实例类型包括 C5.C5d.R5.R5d.除了这四种之外,在AWS国外部分区 ...

  2. iOS ZipArchive文件解压缩

    ZipArchive可以用于iOS中文件的解压缩 压缩文件的方法: //将工程中picture添加到左面111.zip压缩文件中 如果崩溃请更换压缩路径 -(void)testZipFile{ //压 ...

  3. springboot 中使用AOP

    网上关于AOP的例子好多,各种名词解释也一大堆,反正名词各种晦涩,自己写个最最最简单的例子入门mark一下,以后再深入学习. maven依赖 <dependency> <groupI ...

  4. ngnix 参考配置

    #user nobody; worker_processes ; #error_log logs/error.log; #error_log logs/error.log notice; #error ...

  5. ps -ef 和 aux 区别

    Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...

  6. 五分钟上手Git

    团队开发中.遵循一个合理.清晰的Git使用流程.是非常重要的.否则,每一个人都提交一堆杂乱无章的commit,项目非常快就会变得难以协调和维护.以下是ThoughtBot 的Git使用规范流程.我从中 ...

  7. python 基础 9.10 删除数据

      #/usr/bin/python #-*- coding:utf-8 -*- #@Time   :2017/11/24 4:40 #@Auther :liuzhenchuan #@File   : ...

  8. Linq实现between拓展

    先写一个拓展方法 static class Ext { public static IQueryable<TSource> Between<TSource, TKey> (th ...

  9. 【python】-- 元组、字典

    元组 元组其实跟列表差不多,也是存一组数,只不是它一旦创建,便不能再修改,所以又叫只读列表 用途:一般情况下用于自己写的程序能存下数据,但是又希望这些数据不会被改变,比如:数据库连接信息等 1.访问元 ...

  10. mydql练习答案

    .查询“生物”课程比“物理”课程成绩高的所有学生的学号: 思路: 获取所有有生物课程的人(学号,成绩) - 临时表 获取所有有物理课程的人(学号,成绩) - 临时表 根据[学号]连接两个临时表: 学号 ...