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 ;
}

CodeForces161D: Distance in Tree(树分治)的更多相关文章

  1. CodeChef - PRIMEDST Prime Distance On Tree 树分治 + FFT

    Prime Distance On Tree Problem description. You are given a tree. If we select 2 distinct nodes unif ...

  2. [codeforces161D]Distance in Tree(点分治/树形dp)

    题意:求树上距离为k的点对个数: 解题关键:练习一下点分治不用容斥 而直接做的做法.注意先查询,后更新. 不过这个方法有个缺陷,每次以一个新节点为根,必须memset mp数组,或许使用map会好些, ...

  3. POJ 1741 Tree 树分治

    Tree     Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...

  4. POJ 1741.Tree 树分治 树形dp 树上点对

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 24258   Accepted: 8062 Description ...

  5. poj 1744 tree 树分治

    Tree Time Limit: 1000MS   Memory Limit: 30000K       Description Give a tree with n vertices,each ed ...

  6. 【BZOJ-1468】Tree 树分治

    1468: Tree Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 534[Submit][Status][Discuss] ...

  7. HDU 4812 D Tree 树分治+逆元处理

    D Tree Problem Description   There is a skyscraping tree standing on the playground of Nanjing Unive ...

  8. HDU4871 Shortest-path tree(树分治)

    好久没做过树分治的题了,对上一次做是在南京赛里跪了一道很裸的树分治题后学的一道,多校的时候没有看这道题,哪怕看了感觉也看不出来是树分治,看出题人给了解题报告里写了树分治就做一下好了. 题意其实就是给你 ...

  9. HDU4670 Cube number on a tree 树分治

    人生的第一道树分治,要是早点学我南京赛就不用那么挫了,树分治的思路其实很简单,就是对子树找到一个重心(Centroid),实现重心分解,然后递归的解决分开后的树的子问题,关键是合并,当要合并跨过重心的 ...

  10. Codeforces 161D Distance in Tree(树型DP)

    题目链接 Distance in Tree $k <= 500$ 这个条件十分重要. 设$f[i][j]$为以$i$为子树,所有后代中相对深度为$j$的结点个数. 状态转移的时候,一个结点的信息 ...

随机推荐

  1. css3 画三角形

    /*箭头向上*/ .arrow-up { width:0; height:0; border-left:20px solid transparent; border-right:20px solid ...

  2. webstorm取消自动保存并标识修改的文件为星星标记

    a.取消自动保存是去掉一下两个勾选. b.标记星星要勾选下面的选项. c.最终效果.

  3. (25)python urllib库

    urllib包包含4个模块,在python3里urllib导入要用包名加模块名的方式. 1.urllib.request 该模块主要用于打开HTTP协议的URL import urllib.reque ...

  4. 洛谷—— P2515 [HAOI2010]软件安装

    题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...

  5. codevs——1501 二叉树最大宽度和高度

    1501 二叉树最大宽度和高度  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver 题解       题目描述 Description 给出一个二叉树,输出它的 ...

  6. Java中Arrays类与Math类

    Arrays(数组工具类) Java中已经封装好的类,提供大量静态方法供用户对数组的使用. 导包:import java.util.Arrays 1.Arrays.toString(数组) //返回值 ...

  7. 微信小程序,不同的输入框显示

    <!--pages/index/Component/TextInput/TextInput.wxml--> <view class="viewTitle"> ...

  8. Android 学习笔记---获取RadioGroup的选定值

    1,获取RadioGroup控件: RadioGroup radioGroup = (RadioGroup)findViewById(R.id.myRadioGroup); 2,获取RadioButt ...

  9. 嵌入式学习笔记(综合提高篇 第一章) -- 利用串口点亮/关闭LED灯

    1      前言 从踏入嵌入式行业到现在已经过去了4年多,参与开发过的产品不少,有交换机.光端机以及光纤收发器,停车场出入缴费系统,二维码扫码枪,智能指纹锁以及数字IC芯片开发等; 涉及产品中中既有 ...

  10. Python常用的包

    Python常用的处理数据的包和它的Tutorial(点击每个包的名称): Numpy:提供对多维数组的支持,支持矢量运算,速度快 matplotlib.pyplot:图表的绘制 Pandas:基于 ...