题意
给一棵树,每个点有权值,求出有多少子树满足最大最小权值差<= d
以每个点为子树最小点搜索
dp[v] = dp[v] * (dp[u]+1);
if(a[u] == a[sta] && u < sta) continue;//去重
#include<iostream> #include<string.h> #include<stdio.h> using namespace std; const long long maxa = 2005; long long a[maxa]; long long edge[maxa][maxa]; long long o[maxa]; long long dp[maxa]; bool vis[maxa]; const long long mod = 1000000007; long long d, n; long long dfs(long long v, long long sta){ vis[v] = 1; dp[v] = 1; for(long long i = 0; i < o[v]; i++){ long long u = edge[v][i]; if(a[u] < a[sta] || a[u] > a[sta]+d)continue; if(a[u] == a[sta] && u < sta) continue; if(vis[u] == 1) continue; dfs(u, sta); dp[v] = dp[v] * (dp[u]+1); dp[v] %= mod; } } int main(){ scanf("%lld%lld", &d, &n); for(long long i = 1;i <= n; i++){ scanf("%lld", &a[i]); } for(long long i = 1; i < n; i++){ long long x, y; scanf("%lld%lld", &x, &y); edge[x][o[x]++] = y; edge[y][o[y]++] = x; } long long res = 0; for(long long i = 1; i <= n; i ++){ for(long long k = 0; k <= n; k++) dp[k] = 0, vis[k] = 0; dfs(i, i); res += dp[i]; res %= mod; } printf("%lld ", res); }