Game on Tree
一道可爱的期望题。
考虑随机生成一个排列,可以发现由于游戏特性,有一些点实际上是不用被操作的,而一个点不用被操作当且仅当有一个祖先在它前面。所以一个点被操作的概率是它和它的祖先的相对位置中它在最前面的概率,这个概率会等于 $1/(祖先数+1) $ 也就是深度(树根深度为1),最后表现出来的答案会等于 \(\sum\frac{1}{deep_i}\) 。输出即可。
#include<bits/stdc++.h>
//#define feyn
const int N=100010;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int m;
struct edge{
int t,next;
}e[N<<1];
int esum,head[N];
inline void add(int fr,int to){
e[++esum]=(edge){to,head[fr]};head[fr]=esum;
}
double ans;
void dfs(int wh,int fa,int deep){
ans+=(double)1/deep;
for(int i=head[wh],th;i;i=e[i].next){
if((th=e[i].t)==fa)continue;
dfs(th,wh,deep+1);
}
}
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
read(m);int s1,s2;
for(int i=1;i<m;i++){
read(s1);read(s2);
add(s1,s2);add(s2,s1);
}
dfs(1,0,1);
printf("%.6f",ans);
return 0;
}
一如既往,万事胜意