又一次愉快的题意杀……
参考:http://margatroid.xyz/2017-08-12-Codeforces-Round-428-Div-2-C/
题意如果用一句话说就是:求一颗树深度的期望。
数据的输入表示两个节点的连通……我一直以为是有向线段orz
先来思考期望怎么求,期望=概率*权重,这里的权重就是叶节点的深度。而概率P[a]=P[father[a]]*(son of father[a])
可能这么说有些迷,不过各位可以想一下,看成一道生物计算题,母亲白化的前概率1/4,父亲为显性杂合子,那么孩子白化的概率就是1/4*1/2=1/8.实际上这就相当于一棵树的父节点有两个子节点,如果原本的父节点概率为1/4,那么子节点的概率就是1/4*1/2=1/8。
好了,我们不必开个数组存fa[x],事实上这也挺难存,在搜索的时候顺带加一个参数就好了。而且反正cf跑的快,STL随便用,多愉快。程序:
#include <bits/stdc++.h>
using namespace std;
#define maxn 100003
typedef long double ld;
vector<int> v[maxn];
ld ed;
void dfs(int i,int fa,int p,ld pro){
if(v[i].size()==1&&i!=1)
ed+=p*pro;
vector<int>::iterator vi;
for(vi=v[i].begin();vi!=v[i].end();++vi){
if(*vi==fa) continue;
dfs(*vi,i,p+1,pro/(i==1?(v[i].size()):(v[i].size()-1)));
}
}
int main(){
int n;
cin>>n;
int p,q;
for(int i=1;i<n;++i){
cin>>p>>q;
v[p].push_back(q);
v[q].push_back(p);
}
dfs(1,-1,0,1);
cout<<fixed<<setprecision(15)<<ed<<endl;
return 0;
}