BZOJ 3036 3036: 绿豆蛙的归宿 (概率DP)
Posted konjak魔芋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3036 3036: 绿豆蛙的归宿 (概率DP)相关的知识,希望对你有一定的参考价值。
3036: 绿豆蛙的归宿
Time Limit: 2 Sec Memory Limit: 128 MB
Submit: 491 Solved: 354Description
随着新版百度空间的下线,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.00HINT
对于100%的数据 N<=100000,M<=2*NSource
【分析】
这题题意绝对有问题!
3 2
1 2 1
1 3 5
比如这个sample我输出5的代码是错的,AC代码输出3。。。。
不是说起点到终点的路径的期望长度吗?那应该起点到终点的路径才算啊?
唉。。。不懂。。。。我这种理解的代码的话呢,算一下起点到终点的概率,最后除一下这个概率,不能到终点的期望长度视为0.
代码是这样的:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define Maxn 100010 8 #define Maxm 200010 9 10 struct node 11 { 12 int x,y,c,next; 13 }t[Maxm],tt[Maxm]; 14 int len,first[Maxn],d[Maxn]; 15 16 void ins(int x,int y,int c) 17 { 18 d[x]++; 19 t[++len].x=x;t[len].y=y;t[len].c=c; 20 t[len].next=first[x];first[x]=len; 21 } 22 int ln,ft[Maxn]; 23 void INS(int x,int y){tt[++ln].x=x;tt[ln].y=y;tt[ln].next=ft[x];ft[x]=ln;} 24 25 bool vis[Maxn]; 26 double f[Maxn],g[Maxn]; 27 28 void dfs(int x) 29 { 30 if(vis[x]) return;vis[x]=1; 31 for(int i=ft[x];i;i=tt[i].next) 32 { 33 int y=tt[i].y; 34 dfs(y); 35 g[x]+=g[y]*1.0/d[y]; 36 } 37 } 38 39 int n,m; 40 double ffind(int x) 41 { 42 if(x==n) return f[x]=0; 43 if(vis[x]) return f[x];vis[x]=1; 44 for(int i=first[x];i;i=t[i].next) 45 { 46 int y=t[i].y; 47 ffind(y); 48 if(f[y]==0&&y!=n) continue; 49 f[x]+=(f[y]+t[i].c)*1.0/d[x]; 50 } 51 } 52 53 int main() 54 { 55 scanf("%d%d",&n,&m); 56 len=0;ln=0; 57 memset(first,0,sizeof(first)); 58 memset(ft,0,sizeof(ft)); 59 memset(d,0,sizeof(d)); 60 for(int i=1;i<=m;i++) 61 { 62 int x,y,c; 63 scanf("%d%d%d",&x,&y,&c); 64 ins(x,y,c);INS(y,x); 65 } 66 g[1]=1; 67 memset(vis,0,sizeof(vis));vis[1]=1; 68 dfs(n); 69 memset(vis,0,sizeof(vis)); 70 ffind(1); 71 printf("%.2lf\n",f[1]/g[n]); 72 return 0; 73 }
什么都没管的AC代码是这样的:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define Maxn 100010 8 #define Maxm 200010 9 10 struct node 11 { 12 int x,y,c,next; 13 }t[Maxm],tt[Maxm]; 14 int len,first[Maxn],d[Maxn]; 15 16 void ins(int x,int y,int c) 17 { 18 d[x]++; 19 t[++len].x=x;t[len].y=y;t[len].c=c; 20 t[len].next=first[x];first[x]=len; 21 } 22 23 bool vis[Maxn]; 24 double f[Maxn]; 25 26 int n,m; 27 double ffind(int x) 28 { 29 if(vis[x]) return f[x];vis[x]=1; 30 for(int i=first[x];i;i=t[i].next) 31 { 32 int y=t[i].y; 33 ffind(y); 34 f[x]+=(f[y]+t[i].c)*1.0/d[x]; 35 } 36 } 37 38 int main() 39 { 40 scanf("%d%d",&n,&m); 41 len=0; 42 memset(first,0,sizeof(first)); 43 for(int i=1;i<=m;i++) 44 { 45 int x,y,c; 46 scanf("%d%d%d",&x,&y,&c); 47 ins(x,y,c); 48 } 49 memset(vis,0,sizeof(vis)); 50 ffind(1); 51 printf("%.2lf\n",f[1]); 52 return 0; 53 }
【醉了。。。
2017-04-22 11:00:01
以上是关于BZOJ 3036 3036: 绿豆蛙的归宿 (概率DP)的主要内容,如果未能解决你的问题,请参考以下文章