http://codeforces.com/contest/486/problem/D

题意:给定一棵树,点上有权值,以及d,要求有多少种联通块满足最大值减最小值小于等于d。

思路:枚举i作为最大的点权,然后dfs树规一下,就能得出以这个点为最大值的方案数,因为有权值相等的点,所以我们规定一下,只能从标号小的拓展到标号大的,就不会重复了。

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#define ll long long
const ll Mod=;
int tot,go[],first[],next[],a[],d,n;
ll f[];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
void insert(int x,int y){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
}
void add(int x,int y){
insert(x,y);insert(y,x);
}
void dfs(int x,int fa,int fi){
f[x]=;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur==fa) continue;
if (a[pur]>a[fi]) continue;
if (a[fi]-d>a[pur]) continue;
if (a[fi]==a[pur]&&fi>pur) continue;
dfs(pur,x,fi);
f[x]*=(1LL+f[pur]);
f[x]%=Mod;
}
}
int main(){
d=read();n=read();
for (int i=;i<=n;i++)
a[i]=read();
for (int i=;i<n;i++){
int x=read(),y=read();
add(x,y);
}
ll ans=;
for (int i=;i<=n;i++){
for (int j=;j<=n;j++) f[j]=;
dfs(i,,i);
ans=(ans+f[i])%Mod;
}
printf("%I64d\n",ans);
}

最新文章

  1. 解剖SQLSERVER 第二篇 对数据页面头进行逆向(译)
  2. Java多线程之Runable与Thread
  3. Linux C程序内存空间
  4. spring mvc中的json整合
  5. HttpClient post json
  6. POJ 1182 (经典食物链 /并查集扩展)
  7. stl_map,set 用法
  8. 利用智能手机(Android)追踪一块磁铁(转)
  9. springboot整合mq接收消息队列
  10. MySql优化子查询
  11. UE4使用widget创建UI界面播放视频
  12. javap
  13. C# 10分钟完成百度人脸识别——入门篇
  14. Unable to resolve dependency问题解决
  15. React Native 获取组件(Component)在屏幕上的位置
  16. JavaSE基础知识(5)—面向对象(5.6 static关键字)
  17. php同curl post 发送json并返回json数据实例
  18. Python 基础字典的增删改查
  19. 合并两个数组并去重(ES5和ES6两种方式实现)
  20. Spring MVC 返回类型为字符串时, 返回中文变成&quot;?&quot;处理

热门文章

  1. 基于Redis的消息订阅/发布
  2. Linux企业级项目实践之网络爬虫(13)——处理user-agent
  3. bzoj1143
  4. 自定义xcode文件模板
  5. Centos中安装Sublime编辑器
  6. Java IO 概述
  7. BoneCP学习笔记
  8. zoj 3547 The Boss on Mars
  9. java 图片 批量 压缩 +所有压缩
  10. TBB入门