cf161d 求距离为k的点对(点分治,树形dp)

点分治裸题,但是用树形dp也能做

/*
dp[u][k]表示在u下距离k的点数量 
*/
#include<bits/stdc++.h>
using namespace std;
struct Edge{int to,nxt;}edge[100005];
int head[50005],tot,n,k;
long long dp[50005][505],ans;
void init(){
    memset(head,-1,sizeof head);
    tot=0;
}
void addedge(int u,int v){
    edge[tot].to=v;edge[tot].nxt=head[u];head[u]=tot++;
}
void dfs(int u,int pre){ 
    dp[u][0]++;
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        if(v!=pre){
            dfs(v,u);
            for(int j=0;j<k;j++)
                dp[u][j+1]+=dp[v][j];
        }
    }

    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        if(v==pre)continue;
        for(int j=0;j<k;j++){
            ans+=dp[v][j]*dp[u][k-j-1];//距离v为j的点数*距离u为k-j-1的点数 
            if(k-j-1>0)ans-=dp[v][j]*dp[v][k-j-2];//距离v为j的点数*距离v为k-j-2的点数 
        }
    }
    ans+=dp[u][k];
}
int main(){
    init();
    int u,v;
    cin>>n>>k;
    for(int i=1;i<n;i++){
        cin>>u>>v;
        addedge(u,v);addedge(v,u);
    }    
     
    dfs(1,0);
    printf("%d\n",ans/2);
}

 

转载于:https://www.cnblogs.com/zsben991126/p/10333323.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值