【題意】:給出一棵樹,每條邊的長度為1,問樹上有多少點對的距離恰好為k。
【題解】:用樹的分治可解,但是寫起來比較麻煩。
設狀態dp[i][j]表示以i為根的子樹的節點到i的距離恰為j的個數。
然后利用乘法原理求出答案,再把兒子的信息傳給父親。
【代碼】:
1 #include "iostream"
2 #include "cstdio"
3 #include "cstring"
4 #include "algorithm"
5 #include "vector"
6 #include "queue"
7 #include "cmath"
8 #include "string"
9 #include "cctype"
10 #include "map"
11 #include "iomanip"
12 using namespace std;
13 #define pb push_back
14 #define lc(x) (x << 1)
15 #define rc(x) (x << 1 | 1)
16 #define lowbit(x) (x & (-x))
17 #define ll long long
18 #define maxn 50050
19
20 int n, k;
21 ll dp[50050][505];
22 ll ans;
23 vector<int> vec[maxn];
24
25 void dfs(int u, int fa) {
26 memset(dp[u], 0, sizeof(dp[u]));
27 dp[u][0] = 1;
28 int size = vec[u].size();
29 for(int i = 0; i < size; i++) {
30 int v = vec[u][i];
31 if(v == fa) continue;
32 dfs(v, u);
33 for(int j = 1; j <= k; j++)
34 ans += dp[u][j-1] * dp[v][k-j];
35 for(int j = 1; j <= k; j++)
36 dp[u][j] += dp[v][j-1];
37 }
38 }
39
40 int main() {
41 int u, v;
42 while(cin >> n >> k) {
43 for(int i = 0; i < maxn; i++) vec[i].clear();
44 for(int i = 1; i < n; i++) {
45 cin >> u >> v;
46 vec[u].pb(v);
47 vec[v].pb(u);
48 }
49 ans = 0;
50 dfs(1, -1);
51 cout << ans << endl;
52 }
53 return 0;
54 }
55