time limit per test

3 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

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

Copy
5 2
1 2
2 3
3 4
2 5
output

Copy
4
input

Copy
5 3
1 2
2 3
3 4
4 5
output

Copy
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).

这道题就是求树上距离为K的点对数量。以前写过<=K的点对数量,直接<=K的数量 - <K的数量,讲道理应该也是可以的,但是一直TLE11和TLE17样例。。。

最后换了一种写法,直接求,没有中间-子树的过程,最后过了,有点迷。。。

不容斥版的快,就这样。

代码:

 //树分治-点分治
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//#pragma GCC optimize(2)
//#define FI(n) FastIO::read(n)
const int inf=1e9+;
const int maxn=1e5+;
const int maxm=+; int head[maxn<<],tot;
int root,allnode,n,m,k;
bool vis[maxn];
int deep[maxn],dis[maxn],siz[maxn],maxv[maxn];//deep[0]子节点个数(路径长度),maxv为重心节点
int num[maxm],cnt[maxm];
ll ans=; //namespace FastIO {//读入挂
// const int SIZE = 1 << 16;
// char buf[SIZE], obuf[SIZE], str[60];
// int bi = SIZE, bn = SIZE, opt;
// int read(char *s) {
// while (bn) {
// for (; bi < bn && buf[bi] <= ' '; bi++);
// if (bi < bn) break;
// bn = fread(buf, 1, SIZE, stdin);
// bi = 0;
// }
// int sn = 0;
// while (bn) {
// for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
// if (bi < bn) break;
// bn = fread(buf, 1, SIZE, stdin);
// bi = 0;
// }
// s[sn] = 0;
// return sn;
// }
// bool read(int& x) {
// int n = read(str), bf;
//
// if (!n) return 0;
// int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
// for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
// if (bf < 0) x = -x;
// return 1;
// }
//}; inline int read()
{
int x=;char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x;
} struct node{
int to,next,val;
}edge[maxn<<]; void add(int u,int v,int w)//前向星存图
{
edge[tot].to=v;
edge[tot].next=head[u];
edge[tot].val=w;
head[u]=tot++;
} void init()//初始化
{
memset(head,-,sizeof head);
memset(vis,,sizeof vis);
tot=;
} void get_root(int u,int father)//重心
{
siz[u]=;maxv[u]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v==father||vis[v]) continue;
get_root(v,u);//递归得到子树大小
siz[u]+=siz[v];
maxv[u]=max(maxv[u],siz[v]);//更新u节点的maxv
}
maxv[u]=max(maxv[u],allnode-siz[u]);//保存节点size
if(maxv[u]<maxv[root]) root=u;//更新当前子树的重心
} void get_dis(int u,int father)//获取子树所有节点与根的距离
{
if(dis[u]>k) return ;
ans+=num[k-dis[u]];
cnt[dis[u]]++;//计数
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(v==father||vis[v]) continue;
int w=edge[i].val;
dis[v]=dis[u]+w;
get_dis(v,u);
}
} void cal(int u,int now)
{
for(int i=;i<=k;i++){//初始化,清空
num[i]=;
}
num[]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
if(vis[v]) continue;
for(int j=;j<=k;j++){//初始化
cnt[j]=;
}
dis[v]=now;
get_dis(v,u);//跑路径
for(int j=;j<=k;j++){
num[j]+=cnt[j];//计数
}
}
} void solve(int u)//分治处理
{
cal(u,);
vis[u]=;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
int w=edge[i].val;
if(vis[v]) continue;
allnode=siz[v];
root=;
get_root(v,u);
solve(root);
}
} int main()
{
// FI(n);FI(k);
n=read();k=read();
init();
for(int i=;i<n;i++){
int u,v,w;w=;
// FI(u);FI(v);
u=read();v=read();
add(u,v,w);
add(v,u,w);
}
root=;allnode=n;maxv[]=inf;
get_root(,);
solve(root);
printf("%lld\n",ans);
return ;
}

Codeforces 161.D. Distance in Tree-树分治(点分治,不容斥版)-树上距离为K的点对数量-蜜汁TLE (VK Cup 2012 Round 1)的更多相关文章

  1. Codeforces 161 D. Distance in Tree (树dp)

    题目链接:http://codeforces.com/problemset/problem/161/D 题意: 给你一棵树,问你有多少对点的距离为k. 思路: dp[i][j]表示离i节点距离为j的点 ...

  2. codeforces 161 D. Distance in Tree(树形dp)

    题目链接:http://codeforces.com/problemset/problem/161/D 题意:给出一个树,问树上点到点的距离为k的一共有几个. 一道简单的树形dp,算是一个基础题. 设 ...

  3. VK Cup 2012 Round 1 D. Distance in Tree (树形dp)

    题目:http://codeforces.com/problemset/problem/161/D 题意:给你一棵树,问你两点之间的距离正好等于k的有多少个 思路:这个题目的内存限制首先大一倍,他有5 ...

  4. 【树形dp】VK Cup 2012 Round 1 D. Distance in Tree

    统计树中长度为K的路径条数. 用f[u][k]表示从u结点的子树中出发,终止于u结点的长度为k的路径条数. 边dp边统计答案.为了防止重复统计,在枚举子节点的时候,先将该子节点和当前u结点(和前面已经 ...

  5. Codeforces VK Cup 2012 Round 3 A. Variable, or There and Back Again(dfs)

    题目链接:http://codeforces.com/problemset/problem/164/A 思路:用vector分别保留原图和发图,然后分别从val值为1的点正向遍历,va值为2的点反向遍 ...

  6. POJ1741--Tree (树的点分治) 求树上距离小于等于k的点对数

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 12276   Accepted: 3886 Description ...

  7. Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) 菜鸡只会ABC!

    Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) 全场题解 菜鸡只会A+B+C,呈上题解: A. Bear and ...

  8. 洛谷 P3806 【模板】点分治1-树分治(点分治,容斥版) 模板题-树上距离为k的点对是否存在

    P3806 [模板]点分治1 题目背景 感谢hzwer的点分治互测. 题目描述 给定一棵有n个点的树 询问树上距离为k的点对是否存在. 输入格式 n,m 接下来n-1条边a,b,c描述a到b有一条长度 ...

  9. Codeforces Round VK Cup 2015 - Round 1 (unofficial online mirror, Div. 1 only)E. The Art of Dealing with ATM 暴力出奇迹!

    VK Cup 2015 - Round 1 (unofficial online mirror, Div. 1 only)E. The Art of Dealing with ATM Time Lim ...

随机推荐

  1. c#读取数据库bool值

    数据库里bit这个布尔类型的字段,非常实用,但是在c#里读取时,许多人喜欢犯一些错误,导致运行报错. 实际中,有效的正确读取方法只有以下两种: int xxx= Convet.ToInt16(read ...

  2. 2019 创蓝253java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.创蓝253等公司offer,岗位是Java后端开发,因为发展原因最终选择去了创蓝253,入职一年时间了,也成为 ...

  3. 电脑远程连接windows阿里云服务器解决卡顿【小白教程】

    我们在阿里云服务器网页上进行远程连接进行操作,会卡顿.解决办法如下: 1.登录阿里云服务器,进入服务器控制台,复制服务器IP:  2.回到桌面,打开cmd命令窗口,输入mstsc  3.在‘’计算机’ ...

  4. 【开发笔记】- 在Grails下查看打印真实的SQL

    以往我们都是在hibernate里面开启sql,在grails里面只需要在 DataSource.groovy 里面的一个dataSource加入一个 logSql = true即可,但是这样加后发出 ...

  5. Vue学习之品牌案例部分代码小结(二)

    品牌案例的增删查和其他部分效果: <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  6. HTML5 表单新增内容

    一.H5 新增控件 1.datalist 元素 datalist 标签定义选项列表,请与 input 元素配合使用该元素.可为输入框提供一个可选的列表,可以直接选择列表项,也可以不选择列表中的项,自行 ...

  7. JCEF-鼠标右键菜单

    为鼠标添加自定义菜单,比较简单,实现一个Handler就行 Hanler实现类 public class MenuHandler extends CefContextMenuHandlerAdapte ...

  8. Android 中自定义仪表盘

    如图: 自定义属性 values文件下添加 attrs.xml文件 <?xml version="1.0" encoding="utf-8"?> & ...

  9. Java实现简易聊天室

    Java实现简易聊天室 在学习<Java从入门到精通>这本书,网络通信,基于TCP实现的简易聊天室,我这里对书中的代码略做了修改,做个记录. 这里先放一下运行效果图,代码放在最后. 运行效 ...

  10. 【恢复】Redo日志文件丢失的恢复

    第一章 Redo文件丢失的恢复 1.1  online redolog file 丢失 联机Redo日志是Oracle数据库中比较核心的文件,当Redo日志文件异常之后,数据库就无法正常启动,而且有丢 ...