codeforces 161D Distance in Tree (树形DP 经典题)
2015-08-31 15:57
211 查看
题意:给你一颗树,和一个数k,问树中长度为k的路径的条数.
分析:一看就是树形DP的类型.树形DP的特点就是用所有叶子节点的信息更新出其父亲节点,然后这些父亲节点再作为叶子节点,这样层层递归直到根节点.
这里很容易想到的一种叶子节点更新父亲节点的方式如下:
定义dp[i][j]dp[i][j]为节点i为根的所有子树中长度为j的路径的条数.
那么就容易有:dp[i][j]=∑u(u为i的所有子节点)dp[u][j−1]dp[i][j] = \sum_{u(u为i的所有子节点)}dp[u][j - 1]
这样层层的递归调用就可以从子节点更新到根节点了.
但是样根据树的乘法原理算出路径数,还需要一边更新,一边计算.计算的原则是每往该节点加入一个分支,就用该分支和前面已经加入的分支总和来进行组合相乘.
Code:
分析:一看就是树形DP的类型.树形DP的特点就是用所有叶子节点的信息更新出其父亲节点,然后这些父亲节点再作为叶子节点,这样层层递归直到根节点.
这里很容易想到的一种叶子节点更新父亲节点的方式如下:
定义dp[i][j]dp[i][j]为节点i为根的所有子树中长度为j的路径的条数.
那么就容易有:dp[i][j]=∑u(u为i的所有子节点)dp[u][j−1]dp[i][j] = \sum_{u(u为i的所有子节点)}dp[u][j - 1]
这样层层的递归调用就可以从子节点更新到根节点了.
但是样根据树的乘法原理算出路径数,还需要一边更新,一边计算.计算的原则是每往该节点加入一个分支,就用该分支和前面已经加入的分支总和来进行组合相乘.
Code:
#include <iostream> #include <cstdio> #include <vector> using namespace std; const int M = int(1e5 + 1), INF = 0x3fffffff, mod = 1000000007; int dp[50009][509], n, k; long long ans = 0; vector<int> v[50009]; void dfs(int p, int prev) { int u; dp[p][0] = 1; for (int i = 0; i < v[p].size(); i++) { u = v[p][i]; if (u == prev) continue; //只计算当前节点的只树的距离,根节点跳过 dfs(u, p); for (int i = 0; i < k; i++) ans += dp[p][i] * dp[u][k - i -1]; //把当前节点要加入的分支,并组合相乘更新答案 for (int i=0; i<k; i++) dp[p][i + 1] += dp[u][i]; //由子树来更新当前节点 } return; } int main(void) { cin >> n >> k; for (int i = 0; i < n - 1; i++) { int x, y; cin >> x >> y; v[x].push_back(y); v[y].push_back(x); } dfs(n, -1); cout << ans << endl; return 0; }
相关文章推荐
- error MSB6006: cmd.exe exited with code 1.
- JavaWeb中的四大域对象
- 删除模式串中出现的字符
- 3.1 公式3.8证明
- 【LeetCode】88. Merge Sorted Array
- import com.sun.image.codec.jpeg.JPEGCodec不通过 找不到包
- form表单提交和ajax表单提交
- 将List<Map<String, Object>>排序,升序、降序
- 机械臂运动学入门(三)
- js处理文章内容匹配关键词,关键词高亮显示效果的实现
- tac命令以及各种linux文件查看命令
- java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter. <init>(Z)V
- ImageLoader的学习
- jquery实现点击变换导航样式的方法
- Win32 开发问题记录
- JVM(一):体系结构 && 内存模型
- 彩色图像分割方法的汇总
- windows mobile 6.5.3 绕过签名机制 添加根证书到系统 获得特权API
- java集合中对象某属性比较排序Comparable与Comparator
- 库函数 Math