题目链接: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. hdu 1811 Rank of Tetris(拓扑,并查集)

    题意:略 分析:排序先按rating,若相同,则按rp.考虑到每个人的rp均不同,所以rating相同的人必然可以排序.那么只需要考虑rating不同的集合了.  大小关系可以用有向边表示,而大小关系 ...

  2. git设置全局和单个仓库账号和密码

    Git全局配置和单个仓库的用户名邮箱配置 配置全局仓库的账号和密码 git config --global user.name "userName" //你的用户名 git con ...

  3. org.hibernate.type.SerializationException: could not deserialize 反序列化失败

    1.查看实体类有没有实现Serializable接口 例:public class Student implements Serializable { ***** } 2.看表中的字段有没有在实体中进 ...

  4. 【整理】Android中EditText中的InputType类型含义与如何定义( 转 )

    转自:[整理]Android中EditText中的InputType类型含义与如何定义 用到的时候查到了这篇文章觉得很不错,就在此记录下. [背景] 经过一些Android中EditText方面的折腾 ...

  5. html5小趣味知识点系列(一)required

    都知道这个属性是检查你 是否填写了字段也就是说咱们不用判断输入的数值是否为空的情况了 但是这个属性一定要和form配合在一起使用单独的使用是不可以实现的 <!DOCTYPE html> & ...

  6. Unity Editor Inspector编辑模板

    效果图: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEdito ...

  7. 关于IIS上Yii2的Url路由美化

    Yii2默认的路由是酱紫的 http://.../admin/web/index.php?r=site/login 心中理想的美化Url应该这样  http://.../admin/web/site/ ...

  8. C++中面向对象的理解

     1.对于OO(面向对象)的含义,并非每一个人的看法都是同样的. 即使在如今.假设问十个人,可能会得到15种不同的答案.差点儿全部的人都会允许继承和多态是OO中的概念.大多数人还会再加上封装. 另 ...

  9. C语言中的编译时分配内存

    1.栈区(stack) --编译器自动分配释放,主要存放函数的参数值,局部变量值等: 2.堆区(heap) --由程序员分配释放: 3.全局区或静态区 --存放全局变量和静态变量:程序结束时由系统释放 ...

  10. 【BZOJ2081】[Poi2010]Beads hash+调和级数

    [BZOJ2081][Poi2010]Beads Description Zxl有一次决定制造一条项链,她以非常便宜的价格买了一长条鲜艳的珊瑚珠子,她现在也有一个机器,能把这条珠子切成很多块(子串), ...