【题意】:给定一棵树,给定边权的区间[0,L],求最终树的最长路<=S的概率; 

【题解】:武大校赛的树dp,放了好久,看着题解勉强过了。只可以说我的树dp太水了,还停留在背包的阶段。
              设状态dp[i][j]表示以i为根的子树,其叶子结点到i的最长距离为j且该子树最长路径不超过s的概率。
              对于u的一个子树v,先枚举u连v的长度,然后再把之前的子树和v这条链合并,好复杂,不会表达了,直接研究代码吧。

【代码】:
 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 mp make_pair
15 #define fi first
16 #define se second
17 #define lc(x) (x << 1)
18 #define rc(x) (x << 1 | 1)
19 #define lowbit(x) (x & (-x))
20 #define ll long long
21 #define maxn 70
22 #define maxs 530
23 int n, l, s;
24 double dp[maxn][maxs];
25 double son[maxs], tmp[maxs];
26 double e;
27 vector<int> vec[maxn];
28 void dfs(int u, int fa) {
29     memset(dp[u], 0, sizeof(dp[u]));
30     dp[u][0] = 1.0;
31     int size = vec[u].size();
32     for(int i = 0; i < size; i++) {
33         int v = vec[u][i];
34         if(v == fa) continue;
35         dfs(v, u);
36         memset(son, 0, sizeof(son));
37         memset(tmp, 0, sizeof(tmp));
38         for(int j = 0; j <= l; j++)
39             for(int k = 0; k <= s; k++)
40                 if(j + k <= s)
41                     son[j+k] += e * dp[v][k];
42         for(int j = 0; j <= s; j++)
43             for(int k = 0; k <= s - j; k++)
44                 tmp[max(j, k)] += son[j] * dp[u][k];
45         for(int j = 0; j <= s; j++)
46             dp[u][j] = tmp[j];
47     }
48 }
49 
50 int main() {
51     int T, Case = 1;
52     scanf("%d", &T);
53     while(T--) {
54         scanf("%d%d%d", &n, &l, &s);
55         for(int i = 0; i <= n; i++) vec[i].clear();
56         e = 1.0 / (1.0 + l);
57         for(int i = 1; i < n; i++) {
58             int a, b;
59             scanf("%d%d", &a, &b);
60             vec[a].pb(b);
61             vec[b].pb(a);
62         }
63         dfs(1, -1);
64         double ans = 0.0;
65         for(int i = 0; i <= s; i++) ans += dp[1][i];
66         printf("Case %d: %.6f\n", Case++, ans);
67     }
68     return 0;
69 }
70