题目链接在这里:Problem - F - Codeforces
由于期望的可加性,我们可以单独考虑每一个点对整体期望的贡献值,对于一个点,如果它被删掉了,一定是从根节点到它本身这条路径上有点被删了,我们考虑的是这个点对整体的贡献,所以假设它的深度为d,贡献值即为1*(1/d)+0*((d-1)/d),花见一下就是1/d
1 #include "bits/stdc++.h" 2 using namespace std; 3 const int MAX=1e5+5; 4 int n,cnt,d[MAX],num[MAX],nu; 5 vector <int> adj[MAX]; 6 double f[MAX],ans; 7 int main(){ 8 freopen ("f.in","r",stdin); 9 freopen ("f.out","w",stdout); 10 int i,j,u,v,zt,now; 11 vector <int> x; 12 scanf("%d",&n); 13 for (i=1;i<n;i++){ 14 scanf("%d%d",&u,&v); 15 adj[u].push_back(v); 16 adj[v].push_back(u); 17 } 18 queue <int> q; 19 while (!q.empty()) q.pop(); 20 q.push(1);now=1; 21 memset(f,0,sizeof(f)); 22 f[1]=1; 23 while (!q.empty()){ 24 zt=q.front();q.pop(); 25 for (i=1;i<=adj[zt].size();i++) 26 f[now+i]=1.0/(double)(now+i)+(double)(f[now+i-1]+1)*(double)(i)/(double)(now+i); 27 now+=adj[zt].size(); 28 } 29 memset(d,0,sizeof(d)); 30 d[1]=1;q.push(1); 31 memset(num,0,sizeof(num)); 32 nu=0; 33 while (!q.empty()){ 34 zt=q.front();q.pop(); 35 nu=max(nu,d[zt]); 36 num[d[zt]]++; 37 //cout<<zt<<' '<<d[zt]<<' '<<num[d[zt]]<<endl; 38 for (i=0;i<adj[zt].size();i++){ 39 if (d[adj[zt][i]]!=0) continue; 40 d[adj[zt][i]]=d[zt]+1; 41 q.push(adj[zt][i]); 42 //cout<<"fuck "<<zt<<' '<<adj[zt][i]<<endl; 43 } 44 } 45 //cout<<nu<<endl; 46 for (i=1;i<=nu;i++){ 47 //cout<<num[i]<<' '; 48 ans+=(double)num[i]/(double)i; 49 }//cout<<endl; 50 printf("%.8lf",ans); 51 return 0; 52 }