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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值