【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 ...
随机推荐
- 第二章、Tiny4412 U-BOOT移植二 启动分析【转】
本文转载自:http://blog.csdn.net/eshing/article/details/37521481 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.启动过程说明 讲解启动过 ...
- tiny4412 裸机程序 九、串口排查驱动原因及字符图片显示【转】
本文转载自:http://blog.csdn.net/eshing/article/details/37410571 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 一 ...
- 为何Google这类巨头会认为敏捷开发原则是废话?
[编者按]这是一个来自Quora的问题.Rocket程序员Jasmine Adamson在文中表达了敏捷开发原则是废话的观点,他觉得现实生活中没有什么人会推崇这些原则来工作,不过他们仍然在说其所做的是 ...
- codevs3342绿色通道(单调队列优化dp)
3342 绿色通道 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题目描述 Description <思远高考绿色通道>(Green Pass ...
- 【转】关于Java基础你不得不会的34个问题
1. 面向对象和面向过程的区别 面向过程 优点: 性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机.嵌入式开发.Linux/Unix等一般采用面向过程开发,性能是最重要的 ...
- Effective C++ 深入理解inline
Effective C++ 深入理解inline inline语义 inline本义是将所调用函数用自身的函数本体替换之,免受函数调用所招致的额外开销,比宏还要不易出错:但是实际上inline的受编译 ...
- ORA-01012:not logged on的解决办法
conn / as sysdba 报错ORA-01012: not logged on 发生原因:关闭数据库是shutdown 后面没有接关闭参数中的任何一个. nomal ————- —-所有连接都 ...
- android:scaleType 布局文件加载图片时候的显示方式
android:scaleType="center" 以原图的几何中心点和ImagView的几何中心点为基准,按图片的原来size居中显示,不缩放,当图片长/宽超过View的长/宽 ...
- 在下载jar包时,要有三个包,分别为使用的把class、查看文档的api、查看源代码的资源包
字节码包: spring-webmvc-4.1.6.RELEASE.jar 文档包: spring-webmvc-4.1.6.RELEASE-javadoc.jar 资源包: webmvc ...
- Maven 学习(1)
Maven是什么,以及为什么要使用Maven?Maven这个词可以翻译为“知识的积累”,也可以翻译为“专 家”或“内行”.(构建 = 编写源代码+编译源代码+单元测试+生成文档+打包War+部署)Ma ...