【链接】 我是链接,点我呀:)

【题意】

问你一棵树上有多少条长度为k的路径

【题解】

树形dp

size[i]表示以节点i为根节点的子树的节点个数
dp[i][k]表示以i为根节点的子树里面距离节点i的距离为k的节点有多少个.
长度为k的路径有两种情况.
1.这个路径从x开始,只经过x的一个子树.
2.这个路径经过x,横跨x的两个子树.
第一种情况直接累加dp[x][k]即可
第二种情况,可以枚举其中一棵子树y包括的路径长度i,另外一棵子树(其余size[x]-1棵子树都可以作为另外一棵子树)
自然包括的路径长度就是k-i了
累加0.5*dp[y][i-1]*(dp[x][k-i]-dp[y][k-i-1]);
乘0.5是因为把(x,y)和(y,x)都算一遍
(dp[x][k-i]-dp[y][k-i-1])表示的是除去y子树其余size[x]-1棵子树中和x距离为k-i的节点个数
具体的代码中有注释

【代码】

import java.io.*;
import java.util.*; public class Main { static InputReader in;
static PrintWriter out; public static void main(String[] args) throws IOException{
//InputStream ins = new FileInputStream("E:\\rush.txt");
InputStream ins = System.in;
in = new InputReader(ins);
out = new PrintWriter(System.out);
//code start from here
new Task().solve(in, out);
out.close();
} static int N = 50000;
static int K = 500;
static class Task{
long [][]dp;
long ans;
ArrayList []g;
int n,k; void dfs(int x,int fa) {
dp[x][0] = 1;
int len = g[x].size();
for (int i = 0;i < len;i++) {
int y = (int)g[x].get(i);
if (y==fa) continue;
dfs(y,x);
for (int j = 1;j <= k;j++) {
dp[x][j] = dp[x][j] + dp[y][j-1];
}
}
//以x为开始的链
ans = ans + dp[x][k]; //跨过两颗子树
long ans2 = 0;
if (k>=2)//只有长度大于等于2才可能跨过两棵子树
for (int i = 0;i < len;i++) {
int y = (int)g[x].get(i);
if (y==fa) continue;
//以子树y的某个节点作为起点,然后到达x再到达其他位置
for (int l = 1;l<=k-1;l++) {//不能全都在这棵子树里面,得留k-l在另外一个子树
//l是x到y下面的某个节点的长度,比如l=1那么就是到达y节点
//从y的话就是往下l-1长度的点
long temp1 = dp[y][l-1]; //紧接着要找从x出发长度为k-l的点(不能包括y这棵子树)
long temp2 = dp[x][k-l]-dp[y][k-l-1];
ans2 = ans2 + temp1*temp2;
}
}
ans2/=2;//每种都会重复算一次
ans = ans + ans2;
} public void solve(InputReader in,PrintWriter out) {
dp = new long[N+10][K+10];
g = new ArrayList[N+10];
for (int i = 1;i<= N;i++) g[i] = new ArrayList(); n = in.nextInt(); k = in.nextInt(); for (int i = 1;i <= n-1;i++) {
int x,y;
x = in.nextInt();y = in.nextInt();
g[x].add(y);g[y].add(x);
} dfs(1,-1);
out.println(ans);
}
} static class InputReader{
public BufferedReader br;
public StringTokenizer tokenizer; public InputReader(InputStream ins) {
br = new BufferedReader(new InputStreamReader(ins));
tokenizer = null;
} public String next(){
while (tokenizer==null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(br.readLine());
}catch(IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
} public int nextInt() {
return Integer.parseInt(next());
}
}
}

【Codeforces 161D】Distance in Tree的更多相关文章

  1. 【27.91%】【codeforces 734E】Anton and Tree

    time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  2. 【codeforces 791D】 Bear and Tree Jumps

    [题目链接]:http://codeforces.com/contest/791/problem/D [题意] 你可以从树上的节点一次最多走k条边. (称为跳一次); 树为无权树; 然后问你任意两点之 ...

  3. 【树形dp】Distance in Tree

    [CF161.D] Distance in Tree time limit per test 3 seconds memory limit per test 512 megabytes A tree  ...

  4. 【19.27%】【codeforces 618D】Hamiltonian Spanning Tree

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  5. 【27.48%】【codeforces 699D】 Fix a Tree

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. 【Codeforces 1086B】Minimum Diameter Tree

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 统计叶子节点个数m 把每条和叶子节点相邻的边权设置成s/cnt就可以了 这样答案就是2*s/m(直径最后肯定是从一个叶子节点开始,到另外一个叶 ...

  7. 【codeforces 698B】 Fix a Tree

    题目链接: http://codeforces.com/problemset/problem/698/B 题解: 还是比较简单的.因为每个节点只有一个父亲,可以直接建反图,保证出现的环中只有一条路径. ...

  8. 【CodeForces 699D】Fix a Tree

    dfs找出联通块个数cnt,当形成环时,令指向已访问过节点的节点变成指向-1,即做一个标记.把它作为该联通图的根. 把所有联通的图变成一颗树,如果存在指向自己的点,那么它所在的联通块就是一个树(n-1 ...

  9. 【CodeForces 614A】Link/Cut Tree

    题 题意 给你一个区间,求里面有多少个数是k的次方. 分析 暴力,但是要注意这题范围会爆long long,当k=1e8: l=1:r=1e18时 k²=1e16,判断了是≤r,然后输出,再乘k就是1 ...

随机推荐

  1. 自然常数 e 的理解与应用

    某彩票中奖率是百万分之一,则一个人买一百万张彩票仍不中奖的概率是: (1−1106)106≈1e e 往往出现在: 许多微小事件带来的总体变化 随机性和无穷多:

  2. Scala 方法接受变参

    def Parametron(strings:String*): Unit ={ strings.foreach(x=>{ println(x) ") println(s"* ...

  3. Android Studio笔记

    1. toolbar xml: <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:la ...

  4. PCB 规则引擎之JSON对象查看器

    在PCB规则引擎开发中,JavaScript V8引擎是处理业务逻辑的, 当然业务逻辑需要数据支撑才行,  即需有将数据推进入到V8引擎.目前这边数据传输到JavaScript V8引擎以C# Mod ...

  5. curl 采集的时候遇到301怎么办

    采集的时候遇到301,采集数据有错误 $ch = curl_init($url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt( ...

  6. 【NOIP练习赛】开车

    [NOIP练习赛]T2.开车 Description 老司机小 Q 要在一个十字路口指挥车队开车,这个十字路口可 以描述为一个 n*n 的矩阵,其中第 2 行到第 n-1 行都各有一道横向车 道,第 ...

  7. HDU4340 Capturing a country DP

    自己原来写的两个维度的DP有错,看了半天这个大牛的blog.http://blog.csdn.net/cyberzhg/article/details/7840922 题意:A军队和B军队要一起占领一 ...

  8. Linux-fork()函数详解,附代码注释

    // // main.c // Project_C // // Created by LiJinxu on 16/8/13. // Copyright © 2016年 LiJinxu-NEU. All ...

  9. RabbitMQ~消费者实时与消息服务器保持通话

    这个文章主要介绍简单的消费者的实现,rabbitMQ实现的消费者可以对消息服务器进行实时监听,当有消息(生产者把消息推到服务器上之后),消费者可以自动去消费它,这通常是开启一个进程去维护这个对话,它与 ...

  10. Maven 学习(1)

    Maven是什么,以及为什么要使用Maven?Maven这个词可以翻译为“知识的积累”,也可以翻译为“专 家”或“内行”.(构建 = 编写源代码+编译源代码+单元测试+生成文档+打包War+部署)Ma ...