您的位置:首页 > 其它

codeforces #428 Div.2 C - Journey DFS路径长度与数学期望

2017-08-13 00:49 477 查看
原题链接:

codeforces #428 C

大意:

给出一棵树,从根节点 1 开始走,而且不往回走,直到走到叶子。走的过程中去下一个城市的城市概率相同,城市之间路径长为 1 ,求到所有叶子的所有路径的数学期望。

思路:

建树,DFS跑一遍,记录路径长度与概率即可。

一开始没有 get 到概率,WA 了才发现。老实说不 WA 的话,根本没想到要考虑到概率,英文题害人…

PS.这竟然是第一次做数学期望的题,以前遇到好像没有正经去做

代码实现:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(s,t) memset(s,t,sizeof(s))
#define D(v) cout<<#v<<" "<<v<<endl
#define inf 0x3f3f3f3f
#define pb push_back
//#define LOCAL
inline void read(int &x){
x=0;char p=getchar();
while(!(p<='9'&&p>='0'))p=getchar();
while(p<='9'&&p>='0')x*=10,x+=p-48,p=getchar();
}
vector<int> f[100010];
double ac[100010];//记录概率
ll ans[100010];
void dfs(int x,int ret,int last){
for(int i=0;i<f[x].size();i++){
int y=f[x][i];
if(last==y) continue;
int SZ=f[x].size();
ac[y]=ac[x]*1.0/max(SZ-1,1);//计算概率
if(f[y].size()==1){
ans[y]=ret;//记录值
}
dfs(y,ret+1,x);
}
return ;
}
int main() {
int n;
read(n);
mem(ans,0);
for(int i=1;i<=n;i++) ac[i]=1.0;
if(n==1){
puts("0");
return 0;
}
//build graph
for(int i=0;i<n-1;i++){
int x,y;
read(x);read(y);
f[x].pb(y);
f[y].pb(x);
}
//solve
dfs(1,1,1);
double Ans=0;
double B=0;//分母
for(int i=1;i<=n;i++){
if(ans[i]){
Ans+=(ans[i]*ac[i]);
B+=ac[i];
}
}
printf("%.7lf\n",Ans*1.0/B);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息