[CF696B] Puzzles - 树形期望dp
Description
给出一棵树,按随机 DFS 遍历整棵树,求出每个节点期望的时间戳。
Solution
核心想法是,对于一个特定的孩子,其它任何孩子有一半的概率排在它前面,有一半的概率排在它后面
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
int n;
vector<int> g[N];
double f[N];
int siz[N];
void dfs1(int p, int from)
{
siz[p] = 1;
for (auto q : g[p])
{
dfs1(q, p);
siz[p] += siz[q];
}
}
void dfs2(int p, int from)
{
for (auto q : g[p])
{
f[q] = f[p] + 1 + (siz[p] - siz[q] - 1) * 0.5;
dfs2(q, p);
}
}
signed main()
{
ios::sync_with_stdio(false);
cin >> n;
for (int i = 2; i <= n; i++)
{
int x;
cin >> x;
g[x].push_back(i);
}
f[1] = 1;
dfs1(1, 0);
dfs2(1, 0);
for (int i = 1; i <= n; i++)
cout << fixed << setprecision(10) << f[i] << " ";
}