题目链接:

http://codeforces.com/contest/161/problem/D

D. Distance in Tree

time limit per test 3 seconds
memory limit per test 512 megabytes
#### 问题描述
> 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.
#### 输入
> 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.
#### 输出
> 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.
#### 样例
> **sample input**
> 5 2
> 1 2
> 2 3
> 3 4
> 2 5
>
> **sample output**
> 4

题意

给你一颗树,每条边长为1,求所有距离为k的顶点对,(u,v)和(v,u)算一对。

题解

树形dp:

dp[i][j]表示与第i个节点距离为j的节点数。

两次dfs:

第一次求以i为根的子树中与i距离为j的节点数dp[i][j]。

第二次求i与不在i的子树中的节点金额距离为j的节点数。

两次加起来就是表示与i节点距离为j的所有的树上节点数。

答案就是sigma(dp[i][k])。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#define lson (o<<1)
#define rson ((o<<1)|1)
#define M (l+(r-l)/2)
using namespace std; const int maxn=5e4+10;
const int maxm=555; typedef __int64 LL; int n,k;
LL dp[maxn][maxm];
vector<int> G[maxn]; void dfs1(int u,int fa) {
dp[u][0]=1;
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(v==fa) continue;
dfs1(v,u);
for(int j=0;j+1<=k;j++){
dp[u][j+1]+=dp[v][j];
}
}
} LL tmp[maxm];
void dfs2(int u,int fa) {
if(fa!=-1){
tmp[0]=dp[fa][0];
for(int j=1;j<=k;j++){
tmp[j]=dp[fa][j]-dp[u][j-1];
}
for(int j=0;j+1<=k;j++){
dp[u][j+1]+=tmp[j];
}
}
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(v==fa) continue;
dfs2(v,u);
}
} int main() {
scanf("%d%d",&n,&k);
memset(dp,0,sizeof(dp));
for(int i=0; i<n-1; i++) {
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs1(1,-1);
dfs2(1,-1);
LL ans=0;
for(int i=1;i<=n;i++){
ans+=dp[i][k];
}
printf("%I64d\n",ans/2);
return 0;
}

最新文章

  1. sql where传入类型不同,造成查询结果差异问题
  2. FragmentPagerAdapter+ViewPager+Fragment
  3. 继续向peersim的event-driven模式开火!(新手勿喷)
  4. SecureCRT和SecureFx设置中文乱码
  5. js 倒计时点击和当前时间
  6. Linux命令小结:fdisk
  7. ASP.NET控件绑定数据源
  8. AI中去掉页面边框
  9. Unity User Group 北京站图文报道:《Unity3D VR游戏与应用开发》
  10. RollPagerView的用法:
  11. kururu的VHDL学习笔记
  12. Android 5.0 开发者官方网站疏理知识结构
  13. Nim博弈游戏
  14. Fiddler无法正常抓取谷歌等浏览器的请求_解决方案
  15. redis加固
  16. javascript 判断质数
  17. 记录PHP的执行时间
  18. 【APP测试(Android)】--用户体验
  19. ACM-ICPC 2018 沈阳赛区网络预赛 B Call of Accepted(表达式求值)
  20. (三)Lua脚本语言入门(数组)

热门文章

  1. Linux下vi编辑器粘贴复制剪切功能
  2. xode View 的封装
  3. PL/SQL Developer中文注释乱码的解决办法
  4. redis的数据类型
  5. Google搜索镜像
  6. Eclipse 4.6 Neon, could not create the java virtual machine
  7. Learning Scrapy笔记(五)- Scrapy登录网站
  8. 18.python的异常处理
  9. C/C++ 内存管理 (《高质量C++》-- 整理笔记)
  10. jpg图片在IE6、IE7和IE8下不显示解决办法