1. 程式人生 > >bzoj3036--綠豆蛙的歸宿--期望dp

bzoj3036--綠豆蛙的歸宿--期望dp

cst spl span 它的 多少 ont lap 離開 space

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

bzoj3036--綠豆蛙的歸宿--期望dp