树形DP 统计树中长度为K的路径数量 CodeForces 161D Distance in Tree


分类: DP 树形DP codeforces   76人阅读  评论(0)  收藏  举报


Distance in Tree
time limit per test
 3 seconds
memory limit per test
 512 megabytes
input
 standard input
output
 standard output

tree is a connected graph that doesn't contain any cycles.

The distance between two vertices of a tree is the length (in edges) of the shortest path between these vertices.

You are given a tree with n vertices and a positive number k. Find the number of distinct pairs of the vertices which have a distance of exactly k between them. Note that pairs (vu) and (uv) are considered to be the same pair.

Input

The first line contains two integers n and k (1 ≤ n ≤ 500001 ≤ k ≤ 500) — the number of vertices and the required distance between the vertices.

Next n - 1 lines describe the edges as "ai bi" (without the quotes) (1 ≤ ai, bi ≤ nai ≠ bi), where ai andbi are the vertices connected by the i-th edge. All given edges are different.

Output

Print a single integer — the number of distinct pairs of the tree's vertices which have a distance of exactly k between them.

Please do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use thecincout streams or the %I64d specifier.

Sample test(s)
input
5 2
1 2
2 3
3 4
2 5
output
4

题目链接:here


题目大意:给出一棵n个节点的树,统计树中长度为k的路径的条数(1<=n<=50000 , 1<=k<=500)

对于一棵根节点为r的树,经过节点r且长度为k的路径可分为两种情况:

a、节点r为这条路径的端点;

b、节点r为这条路径中途的点;

我们不妨用一个变量dp[r][k]记录通过r且长度为k的路径数目,

则dp[r][k]为a、b两种情况下的和。


[cpp]  view plain copy
  1. #include<cstdio>  
  2. #include<cstring>  
  3. #include<vector>  
  4. #define N 50005  
  5.   
  6. using namespace std;  
  7.   
  8. vector<int> vec[N];  
  9. int dp[N][510],ans;  
  10.   
  11. void dfs(int root,int f,int x)  
  12. {  
  13.     for(int i=0;i<=x;i++) dp[root][i]=0;  
  14.     dp[root][0]=1;  
  15.     for(int i=0;i<vec[root].size();i++) {  
  16.         int son=vec[root][i];  
  17.         if(son!=f) {<span style="font-family: Arial, Helvetica, sans-serif;">//由于是用无向图方式来储存树的,所以加此判断以保持dfs的方向</span>  
  18.             dfs(son,root,x);  
  19.             for(int j=0;j<x;j++) ans+=dp[son][j]*dp[root][x-j-1];  
  20.             for(int j=1;j<=x;j++) dp[root][j]+=dp[son][j-1];  
  21.         }  
  22.     }  
  23. }  
  24.   
  25. int main()  
  26. {  
  27.     int n,k,a,b;  
  28.     while(scanf("%d%d",&n,&k)!=EOF) {  
  29.         for(int i=0;i<n-1;i++) {  
  30.             scanf("%d%d",&a,&b);  
  31.             vec[a].push_back(b);  
  32.             vec[b].push_back(a);  
  33.         }  
  34.         ans=0;  
  35.         dfs(1,0,k);  
  36.         printf("%d\n",ans);  
  37.     }  
  38.     return 0;  
  39. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值