Codeforces 486D D. Valid Sets

http://codeforces.com/contest/486/problem/D

题意:给定一棵树,点上有权值,以及d,要求有多少种联通块满足最大值减最小值小于等于d。

思路:枚举i作为最大的点权,然后dfs树规一下,就能得出以这个点为最大值的方案数,因为有权值相等的点,所以我们规定一下,只能从标号小的拓展到标号大的,就不会重复了。

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #define ll long long
 7 const ll Mod=1000000007;
 8 int tot,go[200005],first[200005],next[200005],a[200005],d,n;
 9 ll f[200005];
10 int read(){
11     int t=0,f=1;char ch=getchar();
12     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
13     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
14     return t*f;
15 }
16 void insert(int x,int y){
17     tot++;
18     go[tot]=y;
19     next[tot]=first[x];
20     first[x]=tot;
21 }
22 void add(int x,int y){
23     insert(x,y);insert(y,x);
24 }
25 void dfs(int x,int fa,int fi){
26     f[x]=1;
27     for (int i=first[x];i;i=next[i]){
28         int pur=go[i];
29         if (pur==fa) continue;
30         if (a[pur]>a[fi]) continue;
31         if (a[fi]-d>a[pur]) continue;
32         if (a[fi]==a[pur]&&fi>pur) continue;
33         dfs(pur,x,fi);
34         f[x]*=(1LL+f[pur]);
35         f[x]%=Mod;
36     }
37 }
38 int main(){
39     d=read();n=read();
40     for (int i=1;i<=n;i++) 
41      a[i]=read();
42     for (int i=1;i<n;i++){
43         int x=read(),y=read();
44         add(x,y);
45     } 
46     ll ans=0;
47     for (int i=1;i<=n;i++){
48      for (int j=1;j<=n;j++) f[j]=0;
49      dfs(i,0,i);
50      ans=(ans+f[i])%Mod;
51     }
52     printf("%I64d\n",ans);
53 }

 

转载于:https://www.cnblogs.com/qzqzgfy/p/5608635.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值