给出一个有向无环的连通图,起点为1,终点为N,每条边都有一个长度。
数据保证从起点出发能够到达图中所有的点,图中所有的点也都能够到达终点。
绿豆蛙从起点出发,走向终点。
到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 1/K 。
现在绿豆蛙想知道,从起点走到终点所经过的路径总长度的期望是多少?
输入格式
第一行: 两个整数 N, M,代表图中有N个点、M条边。
第二行到第 1+M 行: 每行3个整数 a, b, c,代表从a到b有一条长度为c的有向边。
输出格式
输出从起点到终点路径总长度的期望值,结果四舍五入保留两位小数。
数据范围
1≤N≤1051≤N≤105,
1≤M≤2N1≤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 */