bzoj3036--绿豆蛙的归宿--期望dp

Description

随着新版百度空间的下线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿。

给出一个有向无环的连通图,起点为1终点为N,每条边都有一个长度。绿豆蛙从起点出发,走向终点。
到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 1/K 。
现在绿豆蛙想知道,从起点走到终点的所经过的路径总长度期望是多少?

Input

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

Output

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

Sample Input

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

Sample Output

7.00

HINT

对于100%的数据  N<=100000,M<=2*N

题解:

倒着做dp,用f[i]表示i节点到终点n的期望长度。因为走每一条路都是等概率的,对于节点u来说,它到n的期望长度,即为和它相连所有边的长度之和,除以它的度数。

 1 #include<cmath>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<iostream>
 6 using namespace std;
 7 const int maxn=100009;
 8 int m,n,out_degree[maxn],tot=0,head[maxn];
 9 bool vis[maxn];
10 double f[maxn];
11 struct edge
12 {
13     int to,w,nxt;
14 }e[maxn<<1];
15 void addedge(int u,int v,int w)
16 {
17     e[++tot].to=v;
18     e[tot].w=w;
19     e[tot].nxt=head[u];
20     head[u]=tot;
21 }
22 
23 void dfs(int u)
24 {
25     if(vis[u])return;
26     vis[u]=1;
27     for(int i=head[u];i;i=e[i].nxt)
28     {
29         dfs(e[i].to);
30         f[u]+=e[i].w+f[e[i].to];
31     }
32     if(out_degree[u])
33         f[u]/=out_degree[u];
34 }
35 int main()
36 {
37     cin>>n>>m;
38     for(int i=1;i<=m;i++)
39     {
40         int u,v,w;
41         cin>>u>>v>>w;
42         addedge(u,v,w);
43         out_degree[u]++;
44     }
45     dfs(1);
46     printf("%.2lf",f[1]);
47     return 0;
48 }
View Code
原文地址:https://www.cnblogs.com/Beckinsale/p/7575364.html