我是靠谱客的博主 诚心航空,最近开发中收集的这篇文章主要介绍codeforces 161D Distance in Tree (树形DP 经典题),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述


题意:给你一颗树,和一个数k,问树中长度为k的路径的条数.


分析:一看就是树形DP的类型.树形DP的特点就是用所有叶子节点的信息更新出其父亲节点,然后这些父亲节点再作为叶子节点,这样层层递归直到根节点.
这里很容易想到的一种叶子节点更新父亲节点的方式如下:

定义 dp[i][j] 为节点i为根的所有子树中长度为j的路径的条数.
那么就容易有:

dp[i][j]=u(ui)dp[u][j1]

这样层层的递归调用就可以从子节点更新到根节点了.
但是样根据树的乘法原理算出路径数,还需要一边更新,一边计算.计算的原则是每往该节点加入一个分支,就用该分支和前面已经加入的分支总和来进行组合相乘.


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;
}

最后

以上就是诚心航空为你收集整理的codeforces 161D Distance in Tree (树形DP 经典题)的全部内容,希望文章能够帮你解决codeforces 161D Distance in Tree (树形DP 经典题)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部