Codeforces Round #277 (Div. 2)D题
来源:互联网 发布:二维图形变换矩阵 编辑:程序博客网 时间:2024/05/17 07:54
As you know, an undirected connected graph with n nodes and n - 1 edges is called a tree. You are given an integer d and a tree consisting of n nodes. Each node i has a value ai associated with it.
We call a set S of tree nodes valid if following conditions are satisfied:
- S is non-empty.
- S is connected. In other words, if nodes u and v are in S, then all nodes lying on the simple path between u and v should also be presented in S.
- .
Your task is to count the number of valid sets. Since the result can be very large, you must print its remainder modulo 1000000007(109 + 7).
Input
The first line contains two space-separated integers d (0 ≤ d ≤ 2000) and n (1 ≤ n ≤ 2000).
The second line contains n space-separated positive integers a1, a2, ..., an(1 ≤ ai ≤ 2000).
Then the next n - 1 line each contain pair of integers u and v (1 ≤ u, v ≤ n) denoting that there is an edge between u and v. It is guaranteed that these edges form a tree.
Output
Print the number of valid sets modulo 1000000007.
Sample test(s)
input1
1 4
2 1 3 2
1 2
1 3
3 4
output1
8
input2
0 3
1 2 3
1 2
2 3
output2
3
input3
4 8
7 8 7 5 4 6 4 10
1 6
1 2
5 8
1 3
3 5
output3
41
题目大意:给你一棵无根树,节点带权值,给你一个d。要求满足条件的子树有多少个。条件1:子树不为空;条件:2:子树中权值最大-权值最小<=d。
题目分析:。。。见题太少,一时无从下手。正解:由于要使子树中权值最大-权值最小<=d,我们枚举每一个节点,然后以此为根节点宽搜遍历出子树,并要求此点是子树中的权值最小的点。然后只要遍历时遇到分叉点就将所有分叉的情况相乘就可以了。
PS:当遍历到节点权值和当前遍历的根节点权值相等的话会出现重复计算的子树!这里只要在以编号小的节点为根节点时加入不管这种情况,当以编号大的节点碰到这种情况就退出当前遍历,这样处理得话就能让权值相等的只计算一次~
#include<cstdio>#include<cstring>#include<cmath>#include<vector>#include<algorithm>using namespace std;const int inf = (1<<31)-10;const int MOD = (1e9)+7;vector<int>tree[2010];int d,a[2010],q[2010],f[2010];void dfs(int x,int root){ int i,j; q[x]=1;f[x]=1; for (i=0;i<tree[x].size();i++) if (!q[tree[x][i]]) { if (a[root]>a[tree[x][i]]||a[tree[x][i]]>a[root]+d) continue; if (a[root]==a[tree[x][i]]&&tree[x][i]<root) continue;///判重! dfs(tree[x][i],root); f[x]=((long long)f[x]*(f[tree[x][i]]+1))%MOD;///递归求当前节点的数值。 }}int main(){ int i,j,n,u,v,ans=0; scanf("%d%d", &d, &n); for (i=1;i<=n;i++) scanf("%d", &a[i]); for (i=1;i<n;i++) { scanf("%d%d", &u, &v); tree[u].push_back(v); tree[v].push_back(u); } for (i=1;i<=n;i++) { for (j=1;j<=n;j++) { f[j]=0;q[j]=0; } dfs(i,i);///以每一个节点作为最小节点(根)遍历。 ans=(ans+f[i])%MOD; } printf("%d\n", ans); return 0;}
0 0
- Codeforces Round #277 (Div. 2)D题
- Codeforces Round #277 (Div. 2)(D)
- Codeforces Round #261 (Div. 2) D题
- Codeforces Round #277 (Div. 2) D题 树形dp
- Codeforces Round #250 (Div. 2) && (Div. 1) D题
- Codeforces 615D Multipliers (Round #338 (Div. 2) D题)
- Codeforces 617D Polyline (Round #340 (Div. 2) D题)
- Codeforces Round #277 (Div. 2) D Valid Sets
- Codeforces Round #277 (Div. 2) D. Valid Sets (树形DP)
- Codeforces Round #277 (Div. 2) A,B,C,D,E
- Codeforces Round #395 (Div. 2)D(想法题,好题)
- Codeforces Round #103 (Div. 2) D题 SPFA
- Codeforces Round #211 (Div. 2) D题Renting Bikes
- Codeforces Round #236 (Div. 2)D题 Upgrading Array ;dp
- Codeforces Round #275 (Div. 2) D题 (线段树)
- Codeforces Round #323 (Div. 2) D题 (LIS)
- Codeforces Round #342 (Div. 2) A D题
- Codeforces Round #371 (Div. 2)D. Searching Rectangles交互题
- Java学习笔记之面向对象概念
- 【LeetCode】Remove Duplicates from Sorted List
- C 语言程序设计实践 3.13 矩阵坐标
- js控制文本框只输入数字和小数点
- 黑马程序员——OC语言核心语法
- Codeforces Round #277 (Div. 2)D题
- java并发编程(四)同步工具类
- Mac版Cornerstone破解方法
- cocos2d-x 2.2.0 控制lua脚本加载时的搜索路径
- 设计模式:单例模式
- memcache缺点
- C 语言程序设计实践 3.14 摆火柴棒
- leetcode之Clone Graph
- QT我的简易记事本