Description
As you know, an undirected connected graph with n nodes and n - 1 edges is called a tree. You are given an integer d and a tree consisting of n nodes. Each node i has a value a i associated with it.
We call a set S of tree nodes valid if following conditions are satisfied:
1.S is non-empty.
2.S is connected. In other words, if nodes u and v are in S, then all nodes lying on the simple path between u and v should also be presented in S.
3.
Your task is to count the number of valid sets. Since the result can be very large, you must print its remainder modulo 1000000007 (1e9 + 7).
Input
The first line contains two space-separated integers d (0 ≤ d ≤ 2000) and n (1 ≤ n ≤ 2000).
The second line contains n space-separated positive integers a 1, a 2, …, a n(1 ≤ a i ≤ 2000).
Then the next n - 1 line each contain pair of integers u and v (1 ≤ u, v ≤ n) denoting that there is an edge between u and v. It is guaranteed that these edges form a tree.
Output
Print the number of valid sets modulo 1000000007.
Examples
Input
1 4
2 1 3 2
1 2
1 3
3 4
Output
8
Input
0 3
1 2 3
1 2
2 3
Output
3
Input
4 8
7 8 7 5 4 6 4 10
1 6
1 2
5 8
1 3
3 5
6 7
3 4
Output
41
Solution
定义
d
p
[
i
]
dp[i]
dp[i] 为以节点i 为最大值且满足条件的集合数,则以
i
i
i 为根节点遍历整棵树统计贡献
权值比它小的可以直接统计,但权值相等的点则会产生重复计算
故我们将权值相等的点之间的移动强行设为单向即可
Code
#include <bits/stdc++.h>
const int MX = 2e3 + 7;
const int mod = 1e9 + 7;
int n,d,a[MX];
vector<int>G[MX];
ll dp[MX];
void dfs(int u,int fa,int rt){
dp[u] = 1;
for(auto v : G[u]){
if(a[v] > a[rt] || v == fa || a[rt] - a[v] > d) continue;
if(a[v] == a[rt] && v > rt) continue;
dfs(v,u,rt);
dp[u] *= (dp[v] + 1ll);
dp[u] %= mod;
}
}
int main(){
scanf("%d%d",&d,&n);
for(int i = 1;i <= n;++i) scanf("%d",&a[i]);
for(int i = 1;i < n;++i){
int u,v;scanf("%d%d",&u,&v);
G[u].pb(v);G[v].pb(u);
}
ll res = 0;
for(int i = 1; i <= n;++i){
dfs(i,-1,i);
res += dp[i];
res %= mod;
}
printf("%lld\n", res);
return 0;
}