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

7 篇文章 0 订阅
1 篇文章 0 订阅

原题链接:
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值