Codeforces161D【树形DP】

来源:互联网 发布:埃尔金贝勒数据 编辑:程序博客网 时间:2024/06/06 09:37

在读完题以后,一开始不会,我就想那么简单,tm我一定能过…
然后终于屯了几天后拿到加强版的POJ1741,就来再看看///就过了,嘿嘿。


题意:

求一棵树中距离为K的点对有多少个。

思路:

dp[node][j]代表 以节点为node为根的树,从node出发,存在距离长度为 k 的节点数量。
先取答案,再更新
ans += dp[node][k-p] + dp[node_son][p-1];
dp[node][p] += dp[node_son][p-1];
打完发现把以自己为根,从根出发的长度为k的那些dp值加上案例跑不出来,
然后删掉突然就过了!!万脸懵逼。。。
然后仔细一想。。挖草,我是sabi…处理了呀不就是dp[father][0]*dp[son][k-1]这种情况…

Code:

//#include <bits/stdc++.h>#include<iostream>#include<vector>#include<cstdio>#include<string.h>#include<algorithm>using namespace std;typedef pair<int,int> PII;typedef long long LL;//#pragma comment(linker, "/STACK:102400000,102400000")const int N=5e4+10;struct Edge{    int v;    int next;} edge[N<<1];int head[N],tol;int n,k;void init(){    tol=0;    memset(head,-1,sizeof(head));}void add(int u,int v){    edge[tol].v=v;    edge[tol].next=head[u];    head[u]=tol++;}bool vis[N];LL dp[N][550];LL ans;void DFS(int u){    int v;    dp[u][0]=1;    for(int i=head[u];~i;i=edge[i].next){        v = edge[i].v;        if(vis[v]) continue;        vis[v]=true;        DFS(v);        for(int p=1;p<=k;p++)            ans = ans + dp[v][p-1]*dp[u][k-p];        for(int p=0;p<k;p++)            dp[u][p+1] += dp[v][p];    }}void input(){    int u,v;    scanf("%d%d",&n,&k);    init();    for(int i=1; i<n; i++){        scanf("%d%d",&u,&v);        add(u,v);        add(v,u);    }}void solve(){    memset(vis,false,sizeof(vis));    memset(dp,0,sizeof(dp));    ans = 0;    vis[1]=true;    DFS(1);    printf("%lld\n",ans);}int main(){    input();    solve();    return 0;}