Problem
给出一个有向无环图,起点为 终点为 ,每条边都有一个长度,并且从起点出发能够到达所有的点,所有的点也都能够到达终点。绿豆蛙从起点出发,走向终点。
到达每一个顶点时,如果有 条离开该点的道路,绿豆蛙可以选择任意一条道路离开,并且走向每条路的概率为 。
求出从 走到 的所经过的路径总长度期望是多少?
,边数 。
Solution
期望概率DP简单题。
我们用 表示从 到 经过路径总长度的期望值。
那么显然, 。
对于其他的节点 ,假设有 条出边,分别到达 ,边长分别为 ,那么有:
那么我们在这张图上的反图上跑拓扑排序,在拓扑排序的过程中按照公式计算 就行了。
最后的答案就是 。
Code
#include<stack>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 500005
using namespace std;
int n,m,t;
int v[N],w[N],nxt[N];
int first[N],in[N],probablity[N];
double f[N];
void add(int x,int y,int z)
{
nxt[++t]=first[x];
first[x]=t,v[t]=y,w[t]=z;
}
stack<int>stk;
void Topology()
{
int x,i;
for(i=1;i<=n;++i)
if(!in[i]) stk.push(i);
while(!stk.empty())
{
x=stk.top();stk.pop();
for(i=first[x];i;i=nxt[i])
{
in[v[i]]--;
f[v[i]]+=1.0/probablity[v[i]]*(f[x]+w[i]);
if(!in[v[i]]) stk.push(v[i]);
}
}
}
int main()
{
int x,y,z,i;
scanf("%d%d",&n,&m);
for(i=1;i<=m;++i)
{
scanf("%d%d%d",&x,&y,&z);
add(y,x,z),in[x]++,probablity[x]=in[x];
}
f[n]=0,Topology();
printf("%.2lf",f[1]);
return 0;
}