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;
}
posted @ 2018-07-16 14:29  ffgcc  阅读(87)  评论(0编辑  收藏  举报