Codeforces 161D Distance in Tree(树的点分治)

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 (v, u) and (u, v) 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 ≤ n, ai ≠ 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

Note

In the first sample the pairs of vertexes at distance 2 from each other are (1, 3), (1, 5), (3, 5) and (2, 4).



#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

#define N 50010
#define inf 1e9+10
struct node{int to,c,next;}g[N*2];
int head[N],m;
int son[N],f[N];
bool vis[N];
int d[N],deep[N];
int n,sum,root,k,ans;

void add_edge(int from,int to,int cost)
{
    g[++m].next = head[from];
    head[from] = m;
    g[m].to = to; g[m].c = cost;
}

void getroot(int v,int fa)
{
    son[v] = 1; f[v] = 0;
    for(int i = head[v];i;i=g[i].next)
        if(g[i].to != fa && !vis[g[i].to])
        {
            getroot(g[i].to,v);
            son[v] += son[g[i].to];
            f[v] = max(f[v],son[g[i].to]);
        }
    f[v] = max(f[v],sum - son[v]);
    if(f[v] < f[root]) root = v;
}

void getdeep(int v,int fa)
{
    deep[++deep[0]] = d[v];
    for(int i = head[v];i;i=g[i].next)
        if(g[i].to != fa && !vis[g[i].to])
        {
            d[g[i].to] = d[v] + g[i].c;
            getdeep(g[i].to,v);
        }
}

int cal(int v,int cost)
{
    d[v] = cost; deep[0] = 0;
    getdeep(v,0);
    sort(deep+1,deep+deep[0]+1);
    int l = 1,r = deep[0],res = 0;
    for(int l = 1;l < r;l++)
        for(int j=l+1;j<=r;j++){
            if(deep[l]+deep[j]==k) res++;
            else if(deep[l]+deep[j]>k) break;
        }
    return res;
}

void solve(int v)
{
    ans += cal(v,0);
    vis[v] = 1;
    for(int i = head[v];i;i=g[i].next)
        if(!vis[g[i].to])
        {
            ans -= cal(g[i].to,g[i].c);
            sum = son[g[i].to];
            root = 0;
            getroot(g[i].to,0);
            solve(root);
        }
}

int main()
{
    int u,v,w;
    scanf("%d%d",&n,&k);
        ans = root = m = 0;
        memset(vis,0,sizeof(vis));
        memset(head,0,sizeof(head));
        for(int i = 1;i < n;i++)
        {
            scanf("%d%d",&u,&v);
            add_edge(u,v,1);
            add_edge(v,u,1);
        }
        f[0] = inf;
        sum = n;
        getroot(1,0);
        solve(root);
        cout<<ans<<endl;
        return 0;
}






猜你喜欢

转载自www.cnblogs.com/ellery/p/11586903.html