题目链接
题解:
我觉得这题是道好题。
这题一上来我们可能会没什么思路,但是我们思考一下可以发现这题相当于求染到根的概率。
首先我们考虑每一个点有多大概率被染到,我们发现只要这个点本身以及任何一个它的祖先节点被染到它都会变为被染到的状态。
但是这题只会选没被染过的点去染,这个看起来就不太好处理了。
这个题的处理方法是,考虑每个点在它到根的路径上最先被染到的期望次数,这样就保证了这个期望不会包含有被染了很多遍的情况。那么先被选到的期望不难求,就是
1dep[x]
1
d
e
p
[
x
]
,那么根据期望的线性性,我们对每一个点求出
1dep[x]
1
d
e
p
[
x
]
,最后求一个和,就是所有点都被染黑的期望次数。
代码不难写。
#include <bits/stdc++.h>
using namespace std;
int n,hed[200010],cnt,fa[200010];
double ans,dep[200100];
struct node
{
int next,to;
}a[500000];
void add(int from,int to)
{
a[++cnt].to=to;
a[cnt].next=hed[from];
hed[from]=cnt;
}
void dfs(int x)
{
for(int i=hed[x];i;i=a[i].next)
{
int y=a[i].to;
if(y!=fa[x])
{
dep[y]=dep[x]+1;
fa[y]=x;
dfs(y);
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n-1;++i)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dep[1]=1;
dfs(1);
for(int i=1;i<=n;++i)
{
ans+=1/dep[i];
}
printf("%.10lf\n",ans);
return 0;
}