Codeforces 486D Valid Sets(dfs)
题目大意:给定一棵树,每个节点有个权值,现在要选定一些节点,要求非空,并且maxVal-minVal不大于d。问说有多
少种选择方法。
解析:
枚举每个节点作为根节点
默认根节点为权值最大的节点
然后进行dfs
为了避免重复,在两个节点相等时,要求根节点大的时候才能继续进行
由于是乘法,所以longlong 很必要
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define inf 2099999999
#define mod 1000000007
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep1(i,a,b) for(int i=a;i>=b;i--)
const int N=2e3+100;
ll arr[N];
vector<ll>G[N];
ll d;
/**
*/
ll dfs(int now ,int pre ,int rt)
{
ll ret=1;
for(int i=0;i<G[now].size();i++)
{
int y=G[now][i];
if(y!=pre&&arr[rt]>=arr[y]&&arr[rt]-arr[y]<=d&&(arr[rt]!=arr[y]||rt>y))
ret=(ret*(dfs(y,now,rt)+1))%mod;
}
return ret;
}
int main()
{
#ifdef LOCAL_DEFINE
freopen("D://rush.txt", "r", stdin);
#endif
ios::sync_with_stdio(false),cin.tie(0);
ll n,a,b;
cin>>d>>n;
rep(i,1,n) cin>>arr[i];
rep(i,1,n-1)
{
cin>>a>>b;
G[a].pb(b);
G[b].pb(a);
}
ll ans=0;
rep(i,1,n)
{
ans=(ans+dfs(i,0,i))%mod;
}
cout<<ans<<endl;
return 0;
}