题意:给一棵有根树,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 }