CF696B Puzzles 题解

题目传送门

前置知识

树的遍历

解法

目前在 \(fa\) 节点时,搜到子节点 \(x\) 和其他子节点的概率是相等的(因为不需要管具体是哪个节点),均为 \(\frac{1}{2}\)

\(f_{x}\) 表示 \(x\) 时间戳的期望值,状态转移方程为 \(f_{x}=1+f_{fa}+\frac{siz_{fa}-1-siz_{x}}{2}\),边界为 \(f_{1}=1\)

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
struct node
{
    int nxt,to;
}e[100010];
int head[100010],siz[100010],cnt=0;
double f[100010];
void add(int u,int v)
{
    cnt++;
    e[cnt].nxt=head[u];
    e[cnt].to=v;
    head[u]=cnt;
}
void dfs(int x)
{
    siz[x]=1;
    for(int i=head[x];i!=0;i=e[i].nxt)
    {
        dfs(e[i].to);
        siz[x]+=siz[e[i].to];
    }
}
void reroot(int x)
{
    for(int i=head[x];i!=0;i=e[i].nxt)
    {
        f[e[i].to]=1+f[x]+(siz[x]-1-siz[e[i].to])/2.0;
        reroot(e[i].to);
    }
}
int main()
{
    int n,u,v,i;
    cin>>n;
    for(i=2;i<=n;i++)
    {
        cin>>u;
        v=i;
        add(u,v);
    }
    dfs(1);
    f[1]=1;
    reroot(1);
    for(i=1;i<=n;i++)
    {
        printf("%.6lf ",f[i]);
    }
    return 0;
}
posted @ 2024-06-28 17:14  hzoi_Shadow  阅读(11)  评论(0编辑  收藏  举报
扩大
缩小