搜索

题意

给一棵树,每个点有权值,求出有多少子树满足最大最小权值差<= 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);
}
View Code
原文地址:https://www.cnblogs.com/icodefive/p/4093268.html