topic
Bob and Alice went out for their honeymoon, but Alice got lost accidentally. After Bob was sad, he decided to go to find Alice.
Where they honeymoon is a tree with N nodes, Bob will traverse the tree using the following DFS algorithm.
starting_time is an array of capacity n
current_time = 0
dfs(v):
current_time = current_time + 1
starting_time[v] = current_time
Randomize the order of children[v] (each with the same probability)
// children[v] Array of direct children of
v for u in children[v]:
dfs(u)
1 is the root of this tree, Bob will start from 1, i.e. run dfs(1), now he wants to know the expected value of starting_time at each point .
analyze
It is found that when a node is traversed, the subtree rooted at the node must be traversed earlier than its siblings.
If node x is requested, its siblings must contribute to it.
For a parent node F, its sons are S1, S2, S3...
Suppose now to find S1,
because the order of children[v] is randomly arranged, so the probability of its brothers in front of it is \( \dfrac{1}{2}\) .
Total contribution
starting_time[S1]=starting_time[F]+(size[S2]+size[S3]+...)/2+1=starting_time[F]+(size[F]-1-size[S1]) /2+1
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=100005;
using namespace std;
double f[N];
int size[N],fa[N],next[N*2],last[N*2],to[N*2],n,m,tot;
int bj(int x,int y)
{
next[++tot]=last[x];
last[x]=tot;
to[tot]=y;
}
int dg(int x)
{
size[x]=1;
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=fa[x])
{
dg(j);
size[x]+=size[j];
}
}
}
int dg1(int x)
{
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=fa[x])
{
f[j]=f[x]+double(size[x]-1-size[j])*0.5+1;
dg1(j);
}
}
}
int main()
{
scanf("%d",&n);
for(int i=2;i<=n;i++)
{
scanf("%d",&fa[i]);
bj(fa[i],i);
bj(i,fa[i]);
}
dg(1);
f[1]=1;
dg1(1);
for(int i=1;i<=n;i++)
{
printf("%.1lf ",f[i]);
}
}