【Codeforces 161D】Distance in Tree
【链接】 我是链接,点我呀:)
【题意】
问你一棵树上有多少条长度为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的更多相关文章
- 【27.91%】【codeforces 734E】Anton and Tree
time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces 791D】 Bear and Tree Jumps
[题目链接]:http://codeforces.com/contest/791/problem/D [题意] 你可以从树上的节点一次最多走k条边. (称为跳一次); 树为无权树; 然后问你任意两点之 ...
- 【树形dp】Distance in Tree
[CF161.D] Distance in Tree time limit per test 3 seconds memory limit per test 512 megabytes A tree ...
- 【19.27%】【codeforces 618D】Hamiltonian Spanning Tree
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【27.48%】【codeforces 699D】 Fix a Tree
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【Codeforces 1086B】Minimum Diameter Tree
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 统计叶子节点个数m 把每条和叶子节点相邻的边权设置成s/cnt就可以了 这样答案就是2*s/m(直径最后肯定是从一个叶子节点开始,到另外一个叶 ...
- 【codeforces 698B】 Fix a Tree
题目链接: http://codeforces.com/problemset/problem/698/B 题解: 还是比较简单的.因为每个节点只有一个父亲,可以直接建反图,保证出现的环中只有一条路径. ...
- 【CodeForces 699D】Fix a Tree
dfs找出联通块个数cnt,当形成环时,令指向已访问过节点的节点变成指向-1,即做一个标记.把它作为该联通图的根. 把所有联通的图变成一颗树,如果存在指向自己的点,那么它所在的联通块就是一个树(n-1 ...
- 【CodeForces 614A】Link/Cut Tree
题 题意 给你一个区间,求里面有多少个数是k的次方. 分析 暴力,但是要注意这题范围会爆long long,当k=1e8: l=1:r=1e18时 k²=1e16,判断了是≤r,然后输出,再乘k就是1 ...
随机推荐
- 自然常数 e 的理解与应用
某彩票中奖率是百万分之一,则一个人买一百万张彩票仍不中奖的概率是: (1−1106)106≈1e e 往往出现在: 许多微小事件带来的总体变化 随机性和无穷多:
- Scala 方法接受变参
def Parametron(strings:String*): Unit ={ strings.foreach(x=>{ println(x) ") println(s"* ...
- Android Studio笔记
1. toolbar xml: <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:la ...
- PCB 规则引擎之JSON对象查看器
在PCB规则引擎开发中,JavaScript V8引擎是处理业务逻辑的, 当然业务逻辑需要数据支撑才行, 即需有将数据推进入到V8引擎.目前这边数据传输到JavaScript V8引擎以C# Mod ...
- curl 采集的时候遇到301怎么办
采集的时候遇到301,采集数据有错误 $ch = curl_init($url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt( ...
- 【NOIP练习赛】开车
[NOIP练习赛]T2.开车 Description 老司机小 Q 要在一个十字路口指挥车队开车,这个十字路口可 以描述为一个 n*n 的矩阵,其中第 2 行到第 n-1 行都各有一道横向车 道,第 ...
- HDU4340 Capturing a country DP
自己原来写的两个维度的DP有错,看了半天这个大牛的blog.http://blog.csdn.net/cyberzhg/article/details/7840922 题意:A军队和B军队要一起占领一 ...
- Linux-fork()函数详解,附代码注释
// // main.c // Project_C // // Created by LiJinxu on 16/8/13. // Copyright © 2016年 LiJinxu-NEU. All ...
- RabbitMQ~消费者实时与消息服务器保持通话
这个文章主要介绍简单的消费者的实现,rabbitMQ实现的消费者可以对消息服务器进行实时监听,当有消息(生产者把消息推到服务器上之后),消费者可以自动去消费它,这通常是开启一个进程去维护这个对话,它与 ...
- Maven 学习(1)
Maven是什么,以及为什么要使用Maven?Maven这个词可以翻译为“知识的积累”,也可以翻译为“专 家”或“内行”.(构建 = 编写源代码+编译源代码+单元测试+生成文档+打包War+部署)Ma ...