A 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 ≤ 50000, 1 ≤ 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 and bi 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 the cin, cout streams or the %I64d specifier.

Examples

Input
5 2
1 2
2 3
3 4
2 5
Output
4
Input
5 3
1 2
2 3
3 4
4 5
Output
2

题意:给定一棵树,问树上有多少个点对距离是K(K<=500)。

思路:明显的基础分治题,分别累计经过根节点的距离为K的点对。说他基础是以为既不需要排序,也不需要去重。复杂度O(NlogN*K)

(感悟:分治=若干个小分治+线性解决当前层 =NlogN。

分治=若干个小分治+logN解决当前层 =NlogN*logN。

分治=若干个小分治+K*线性解决当前层 =N*K*logN。

#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int Laxt[maxn],Next[maxn],To[maxn];
int sz[maxn],son[maxn],root,cnt,N,K,ans,sn; //sn,小树的大小。
int num[],tnum[],vis[maxn];
void read(int &x){
x=; char c=getchar();
while(c>''||c<'') c=getchar();
while(c>=''&&c<='') x=(x<<)+(x<<)+c-'',c=getchar();
}
void add(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt; To[cnt]=v;
}
void getroot(int u,int fa)
{
sz[u]=; son[u]=;
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i];
if(v==fa||vis[v]) continue;
getroot(v,u); sz[u]+=sz[v];
son[u]=max(son[u],sz[v]);
}
son[u]=max(sz[u],sn-son[u]);
if(root==||son[root]>son[u]) root=u;
}
void getdep(int u,int fa,int dis)
{
if(K>=dis) ans+=num[K-dis],tnum[dis]++;
if(K==dis) return ;
for(int i=Laxt[u];i;i=Next[i])
if(To[i]!=fa&&!vis[To[i]])
getdep(To[i],u,dis+);
}
void dfs(int u)
{
vis[u]=;
for(int i=;i<=K;i++) num[i]=; num[]=;
for(int i=Laxt[u];i;i=Next[i]){ //暴力部分
if(vis[To[i]]) continue;
for(int j=;j<=K;j++) tnum[j]=;
getdep(To[i],,);
for(int j=;j<=K;j++) num[j]+=tnum[j];
} for(int i=Laxt[u];i;i=Next[i]){ //以大化小,分治部分
if(vis[To[i]]) continue;
sn=sz[To[i]]; root=;
getroot(To[i],u); dfs(root);
}
}
int main()
{
int u,v; scanf("%d%d",&N,&K);
for(int i=;i<N;i++){
read(u) ; read(v) ;
add(u,v); add(v,u);
}
root=; sn=N; getroot(,); dfs(root);
printf("%d\n",ans);
return ;
}

最新文章

  1. Sharepoint学习笔记—习题系列--70-576习题解析 -(Q128-Q130)
  2. IOS开发之功能模块--输入框随着键盘的位置移动而移动
  3. HTML标签显示在页面上
  4. SQL计算时间差,要精确到小时分钟秒
  5. NI Labview 将图形化系统设计用于肿瘤治疗
  6. kafka go producer 启动基本配置
  7. 黑马程序员+Winform基础(上)
  8. NetBios网络基础及编程
  9. some knowledge of maven {maven实战}
  10. 日期选择控件-laydate
  11. shiro中unauthorizedUrl不起作用
  12. 关于redhat6的服务说明
  13. Python GUI with Tkinter (from youtube) 在youtube上能找到很多编程视频...
  14. Bad Hair Day(单调栈 )
  15. JS中让新手倍感震惊、违反直觉、出乎意料、的一些知识点汇总记录
  16. VFIO PF SRIOV IOMMU UIO概念解释、关联
  17. winform复制文件到指定目录
  18. Sitecore系统教程即时查阅编辑内容
  19. 【Django】网页跳转的问题
  20. 自然语言交流系统 phxnet团队 创新实训 项目博客 (十三)

热门文章

  1. ubuntu下U盘变为只读
  2. Java面试题总结之数据结构、算法和计算机基础(刘小牛和丝音的爱情故事1)
  3. 《Java虚拟机原理图解》 1.2.3、Class文件中的常量池详解(下)
  4. linux 每天备份mysql数据
  5. ubuntu 14.04安装nodejs
  6. 【整理】nand相关
  7. ArcGIS教程:分水岭
  8. java内部类的一些看法
  9. Python开发【2.2 异常处理】
  10. rtsp 播放器