题意:给一棵有根树,dfs这棵树时,走向每个子节点的概率相等,求这棵树每个点的dfs时间戳期望。

题解:考虑一个节点,其他兄弟节点对它有贡献当且仅当其他节点在它之前被遍历,概率是1/2的。

所以ans[x] = ans[fa] + 1 + sz[brother]  / 2;

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 100000
 4 #define LL long long
 5 
 6 inline LL read() {
 7     LL x = 0, f = 1; char a = getchar();
 8     while(a < '0' || a > '9') { if(a == '-') f = -1; a = getchar(); }
 9     while(a >= '0' && a <= '9') x = x *10 + a - '0', a = getchar();
10     return x * f;
11 }
12 
13 int n, head[N + 5], sz[N + 5], cnt = 1;
14 double ans[N + 5];
15 
16 struct edges{
17     int to, next;
18 }e[2 * N + 5];
19 
20 inline void insert(int x) {
21     int u = x, v = read();
22     e[++cnt] = (edges) {u, head[v]}; head[v] = cnt;
23     e[++cnt] = (edges) {v, head[u]}; head[u] = cnt;
24 }
25 
26 void dfs(int x, int fa){
27     sz[x] = 1;
28     for(int i = head[x]; i; i = e[i].next) {
29         if(e[i].to == fa) continue;
30         dfs(e[i].to, x)    ;
31         sz[x] += sz[e[i].to];
32     }
33 }
34 
35 void Dfs(int x, int fa) {
36     for(int i = head[x]; i; i = e[i].next) {
37         if(e[i].to == fa) continue;        
38         ans[e[i].to] = 1.0 * (sz[x] - 1 - sz[e[i].to]) / 2.0 + 1.0 + ans[x];
39         Dfs(e[i].to, x);
40     }
41 }
42 
43 int main() {
44     n = read();
45     for(int i = 2; i <= n; i++) insert(i);
46     dfs(1, 0);
47     ans[1] = 1;
48     Dfs(1, 0);
49     for(int i = 1; i <= n; i++) printf("%.7lf\n",ans[i]);
50     return  0;
51 }