CF161D Distance in Tree

题目大意

输入点数为$N$一棵树

求树上长度恰好为$K$的路径个数

题解

  据说正解点分

  然而我用树形dp的,简单易懂

  虽然跑得没有点分快就是了

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #define ll long long
 5 using namespace std;
 6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 7 char buf[1<<21],*p1=buf,*p2=buf;
 8 inline int read(){
 9     #define num ch-'0'
10     char ch;bool flag=0;int res;
11     while(!isdigit(ch=getc()))
12     (ch=='-')&&(flag=true);
13     for(res=num;isdigit(ch=getc());res=res*10+num);
14     (flag)&&(res=-res);
15     #undef num
16     return res;
17 }
18 const int N=50005;
19 int ver[N<<1],head[N],Next[N<<1];
20 ll res,f[N][505],ans;int n,k,tot;
21 inline void add(int u,int v){
22     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
23     ver[++tot]=u,Next[tot]=head[v],head[v]=tot;
24 }
25 void dfs(int u,int fa){
26     f[u][0]=1;
27     for(int i=head[u];i;i=Next[i]){
28         int v=ver[i];if(v==fa) continue;dfs(v,u);
29         for(int j=1;j<=k;++j) f[u][j]+=f[v][j-1];
30     }
31     ans+=f[u][k],res=0;
32     for(int i=head[u];i;i=Next[i]){
33         int v=ver[i];if(v==fa) continue;
34         for(int j=1;j<k;++j) res+=f[v][j-1]*(f[u][k-j]-f[v][k-j-1]);
35     }
36     ans+=res>>1;
37 }
38 int main(){
39     n=read(),k=read();
40     for(int i=1;i<n;++i){
41         int u=read(),v=read();
42         add(u,v);
43     }
44     dfs(1,0);
45     printf("%lld\n",ans);
46     return 0;
47 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9483001.html