【题解】:用树的分治可解,但是写起来比较麻烦。
设状态dp[i][j]表示以i为根的子树的节点到i的距离恰为j的个数。
然后利用乘法原理求出答案,再把儿子的信息传给父亲。
1 #include<cstdlib>
2 #include<iostream>
3 #include<cstdio>
4 #include<cmath>
5 #include<cstring>
6 #include<string>
7 #include<map>
8 #include <algorithm>
9 #include<set>
10 #include<vector>
11 #define LL long long
12 #define inf 0x7fffffff
13 #define E 1e-9
14 #define N 50009
15 #define M 509
16 using namespace std;
17 int m,n,k;
18 LL d[N][M];
19 vector<int> g[N];
20 LL ans;
21 void dfs(int x,int f)
22 {
23 int s=g[x].size();
24 d[x][0]=1;//本身自己
25 for(int i=0; i<s; i++)
26 {
27 int u=g[x][i];
28 if(u==f)
29 continue;
30 dfs(u,x);
31 for(int j=0; j<k; j++)
32 ans+=d[u][j]*d[x][k-1-j];//相加等于k-1
33 for(int j=1; j<=k; j++)
34 d[x][j]+=d[u][j-1];
35 }
36 }
37 int main()
38 {
39 #ifndef ONLINE_JUDGE
40 freopen("ex.in","r",stdin);
41 #endif
42 scanf("%d%d",&n,&k);
43 ans=0;//全局
44 int x,y;
45 for(int i=1; i<n; ++i)
46 {
47 scanf("%d%d",&x,&y);
48 g[x].push_back(y);
49 g[y].push_back(x);
50 }
51 dfs(x,-1);
52 printf("%I64d\n",ans);
53
54 return 0;
2 #include<iostream>
3 #include<cstdio>
4 #include<cmath>
5 #include<cstring>
6 #include<string>
7 #include<map>
8 #include <algorithm>
9 #include<set>
10 #include<vector>
11 #define LL long long
12 #define inf 0x7fffffff
13 #define E 1e-9
14 #define N 50009
15 #define M 509
16 using namespace std;
17 int m,n,k;
18 LL d[N][M];
19 vector<int> g[N];
20 LL ans;
21 void dfs(int x,int f)
22 {
23 int s=g[x].size();
24 d[x][0]=1;//本身自己
25 for(int i=0; i<s; i++)
26 {
27 int u=g[x][i];
28 if(u==f)
29 continue;
30 dfs(u,x);
31 for(int j=0; j<k; j++)
32 ans+=d[u][j]*d[x][k-1-j];//相加等于k-1
33 for(int j=1; j<=k; j++)
34 d[x][j]+=d[u][j-1];
35 }
36 }
37 int main()
38 {
39 #ifndef ONLINE_JUDGE
40 freopen("ex.in","r",stdin);
41 #endif
42 scanf("%d%d",&n,&k);
43 ans=0;//全局
44 int x,y;
45 for(int i=1; i<n; ++i)
46 {
47 scanf("%d%d",&x,&y);
48 g[x].push_back(y);
49 g[y].push_back(x);
50 }
51 dfs(x,-1);
52 printf("%I64d\n",ans);
53
54 return 0;
55 }