codeforces 161D - Distance in Tree(树形dp)

题目大意:

求出树上距离为k的点对有多少个。

思路分析:

dp[i][j] 表示 i 的子树中和 i 的距离为 j 的点数有多少个。注意dp[i] [0] 永远是1的。

然后在处理完一颗子树后,就把自身的dp 更新。

更新之前更新答案。

如果这颗子树到 i 有 x 个距离为j的。那么答案就要加上 dp[i] [ k-j-1] * x;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 50005
using namespace std;
typedef long long ll;
ll dp[maxn][505];

int head[maxn];
int to[maxn<<1];
int next[maxn<<1];
int tot;
int n,k;
void addedge(int u,int v)
{
    tot++;
    next[tot]=head[u];
    to[tot]=v;
    head[u]=tot;
}

bool vis[maxn];
ll ans=0;
void dfs(int x)
{
    dp[x][0]=1;
    for(int p=head[x];p;p=next[p])
    {
        if(vis[to[p]])continue;

        vis[to[p]]=true;
        dfs(to[p]);

        for(int i=0;i<k;i++)
        {
            ans+=dp[to[p]][k-i-1]*dp[x][i];
        }
        for(int i=0;i<=k;i++)
        {
            if(i)dp[x][i]+=dp[to[p]][i-1];
            else dp[x][i]=1;
        }
    }
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<n;i++)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        addedge(l,r);
        addedge(r,l);
    }

    memset(vis,false,sizeof vis);
    memset(dp,0,sizeof dp);
    vis[1]=true;
    dfs(1);
    printf("%I64d\n",ans);
    return 0;
}

codeforces 161D - Distance in Tree(树形dp)

时间: 2024-08-03 11:28:34

codeforces 161D - Distance in Tree(树形dp)的相关文章

CF 161D Distance in Tree 树形DP

一棵树,边长都是1,问这棵树有多少点对的距离刚好为k 令tree(i)表示以i为根的子树 dp[i][j][1]:在tree(i)中,经过节点i,长度为j,其中一个端点为i的路径的个数dp[i][j][0]:在tree(i)中,经过节点i,长度为j,端点不在i的路径的个数 则目标:∑(dp[i][k][0]+dp[i][k][1])初始化:dp[i][0][1]=1,其余为0 siz[i]:tree(i)中,i与离i最远的点的距离递推:dp[i][j][0]+=dp[i][j-l][1]*dp[

codeforces161D - Distance in Tree 树形dp

题意:给你一棵树,问你树中距离为k的有多少种情况. 解题思路:树形dp  维护每个节点(1-K)深度的情况, 解题代码: 1 // File Name: 161d.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月03日 星期日 19时20分10秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #incl

Codeforces 461B Appleman and Tree(树形dp)

题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每个节点的父亲节点,以及每个点的颜色(0表示白色,1表示黑色),切断这棵树的k条边,使得树变成k+1个联通分量,保证每个联通分量有且仅有1个黑色节点.问有多少种分割方法. 解题思路:树形dp,dp[i][0]和dp[i][1]分别表示子树一下的分割方法中,i节点所在联通块不存在黑节点和已经存在一个黑节点的方案数. #include <cstdio> #include <c

Codeforces 462D Appleman and Tree 树形dp

题目链接:点击打开链接 题意: 给定n个点的树, 0为根,下面n-1行表示每个点的父节点 最后一行n个数 表示每个点的颜色,0为白色,1为黑色. 把树分成若干个联通块使得每个联通块有且仅有一个黑点,问有多少种分法(结果mod1e9+7) 思路: 树形dp,每个点有2个状态,已经归属于某个黑点和未归属于某个黑点. #include <cstdio> #include <vector> #include <iostream> using namespace std; #de

CodeForces 161D Distance in Tree【树形DP】

<题目链接> 题目大意:一颗无向无环树,有n个顶点,求其中距离为k的点对数是多少,(u,v)与(v,u)为同一点对. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 #define N int(5e4+10) 7 int n,k,ans,cnt; 8 int dp[N][510],head[N]; 9 struct Edge{

Codeforces 461B. Appleman and Tree[树形DP 方案数]

B. Appleman and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are color

codeforces 416B. Appleman and Tree 树形dp

题目链接 Fill a DP table such as the following bottom-up: DP[v][0] = the number of ways that the subtree rooted at vertex v has no black vertex. DP[v][1] = the number of ways that the subtree rooted at vertex v has one black vertex. The recursion pseudo

Codeforces 161D Distance in Tree

题目大意:给出一棵n个节点的树,统计树中长度为k的路径的条数(1<=n<=50000 , 1<=k<=500) 思路:树分治! #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> #define ll long long int n,K,son[500005],F[500005],sum; ll

Bestcoder round #65 &amp;&amp; hdu 5593 ZYB&#39;s Tree 树形dp

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 354    Accepted Submission(s): 100 Problem Description ZYB has a tree with N nodes,now he wants you to solve the numbers of nodes distanced no m