zoukankan      html  css  js  c++  java
  • Valid Sets

    Codeforces Round #277 (Div. 2)   D. Valid Sets

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

    解题思路:1.首先,考虑没有树的节点value情况,那就简化成了求一颗树的所有子树,用dp很容易就可以得到。

          即:dp[u]=∏(dp[v]+1)    ,其中u是父节点,v是子节点。

         2.需要寻找节点value之差不超过d的子树,考虑到找到的子树一定会存在一个value最小的点,所以把每个节点做为根节点,

          形成n颗所有节点满足 a[v]>=a[root]&&a[v]<=a[root]+d的树,把每颗树的根节点的dp[root]加起来就是总数。

         3.注意中间过程的取模,同时注意出现节点value一样的情况,避免重复计算。

    代码如下:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <vector>
     4 #include <cmath>
     5 #include <algorithm>
     6 
     7 using namespace std;
     8 
     9 const int maxn = 2000 + 10;
    10 const int MOD = 1e9 + 7;
    11 
    12 vector<int> node[maxn];
    13 int a[maxn];
    14 long long dp[maxn];
    15 bool f[maxn];
    16 int d, n;
    17 
    18 void dfs(int u, int root)
    19 {
    20     for (int i = 0; i < node[u].size(); i++)
    21     {
    22         f[u] = 1;
    23         int v = node[u][i];
    24         if(f[v] == 0 && ((a[v] > a[root] && a[v] <= a[root] + d) || (a[v] == a[root] && v > root)))
    25         {
    26             dfs(v, root);
    27             dp[u] = (dp[u] * (dp[v] + 1)) % MOD;
    28         }
    29     }
    30 }
    31 
    32 int main()
    33 {
    34     while(scanf("%d%d", &d, &n) != EOF)
    35     {
    36         for (int i = 1; i <= n; i++)
    37         {
    38             scanf("%d", &a[i]);
    39         }
    40         for (int i = 0; i < n - 1; i++)
    41         {
    42             int u, v;
    43             scanf("%d%d", &u, &v);
    44             node[u].push_back(v);
    45             node[v].push_back(u);
    46         }
    47         int sum = 0;
    48         for (int i = 1; i <= n; i++)
    49         {
    50             memset(f, 0, sizeof(f));
    51             for (int j = 1; j <= n; j++)
    52             {
    53                 dp[j] = 1;
    54             }
    55             dfs(i, i);
    56             sum = (sum + dp[i]) % MOD;
    57         }
    58         printf("%d
    ", sum);
    59     }    
    60     
    61     
    62 
    63     return 0;
    64 }

    AC如下:

  • 相关阅读:
    线程原理 创建方式
    Chapter17 【异常、线程】
    驱动
    java中Super到底是什么意思
    Java 8后的首个长期支持版本Java 11
    OpenJDK和JDK区别
    异常
    模拟斗地主洗牌发牌
    Debug追踪
    Python 垃圾回收机制详细
  • 原文地址:https://www.cnblogs.com/sunjieee/p/4115244.html
Copyright © 2011-2022 走看看