给出一个有向无环的连通图,起点为1,终点为N,每条边都有一个长度。

数据保证从起点出发能够到达图中所有的点,图中所有的点也都能够到达终点。

绿豆蛙从起点出发,走向终点。

到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 1/K 。

现在绿豆蛙想知道,从起点走到终点所经过的路径总长度的期望是多少?

输入格式

第一行: 两个整数 N, M,代表图中有N个点、M条边。

第二行到第 1+M 行: 每行3个整数 a, b, c,代表从a到b有一条长度为c的有向边。

输出格式

输出从起点到终点路径总长度的期望值,结果四舍五入保留两位小数。

数据范围

1N1051≤N≤105,
1M2N1≤M≤2N

输入样例:

4 4
1 2 1
1 3 2
2 3 3
3 4 4

输出样例:

7.00



题意:起点为1,终点为n,在这个有向图上求1-n的路径长度的期望,每个点的分支是K条,那么这k条走到的概率为1/k
思路:首先我们计算的时候,因为当前点的相邻边是k条,那么每条的概率为1/k,那么路径就是1/k*(当前边长),我们可以发现当前点是由前驱的概率传过来的,我们可以计算出到每个点的概率是多少
然后再去乘当前边长度,这样点与点互相传递即可,然后我们知道具体思路后,可以转化一个dp
f[x]代表当前点到终点的期望长度,然后可以推导f[x]=1/k累加(1-k)(f[y]+边长)
f[1]即为所求答案

#include<bits/stdc++.h>
#define maxn 100005
#define mod 1000000007
using namespace std;
typedef long long ll; 
ll n,m;
ll d[maxn+10];
ll deg[maxn+10]; 
double f[maxn+10];
vector<pair<ll,ll> > mp[maxn+10];
ll x,y,z;
int main(){
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>x>>y>>z;
        mp[y].push_back(make_pair(x,z));
        d[x]++;
        deg[x]++; 
    }
    queue<ll> q;
    q.push(n);
    while(!q.empty()){
        ll w=q.front();
        q.pop();
        for(int i=0;i<mp[w].size();i++){
            pair<ll,ll> v=mp[w][i];
            f[v.first]+=(double)(f[w]+v.second)/deg[v.first];
            if(--d[v.first]==0){
                q.push(v.first);
            } 
        }
    }
    printf("%.2lf",f[1]);
} 
/*
4 4
1 2 1
1 3 2
2 3 3
3 4 4
*/