题意:
点1为根。
解法:
染色操作可以等价于随机生成[1,n]的排列,
然后遍历排列,遇到没有染色的点就将其染色,并且操作次数+1,
总期望次数=每个点被染色的期望次数的和,
由于一轮下来每个点最多被染色一次,
所以每个点被染色的期望次数=全排列中这个点被染色的概率之和.
一个点会被染色只有当他的祖先都在这个点后面才行,
设sz[x]为x的祖先的数量(包含x),
x在长度为sz[x]的序列最前面的概率为1/sz[x],
因此被染色的期望次数为1/sz[x].
对1/sz[i]求和就是答案.
code:
#include <bits/stdc++.h>
using namespace std;
const int maxm=3e5+5;
vector<int>g[maxm];
int sz[maxm];//sz[x]表示x的祖先数量(包括自己)
int n;
void dfs(int x,int fa){
sz[x]++;
for(int v:g[x]){
if(v==fa)continue;
sz[v]+=sz[x];
dfs(v,x);
}
}
signed main(){
cin>>n;
for(int i=1;i<n;i++){
int a,b;cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
dfs(1,1);
double ans=0;
for(int i=1;i<=n;i++){
ans+=1.0/sz[i];
}
printf("%.10f\n",ans);
return 0;
}