首页 > 代码库 > 【BZOJ 3036】 3036: 绿豆蛙的归宿 (概率DP)

【BZOJ 3036】 3036: 绿豆蛙的归宿 (概率DP)

3036: 绿豆蛙的归宿

Time Limit: 2 Sec  Memory Limit: 128 MB
Submit: 491  Solved: 354

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

Source

Poetize3

 

 

【分析】

  这题题意绝对有问题!

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 }
View Code

 

  什么都没管的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 }
View Code

【醉了。。。

 

2017-04-22 11:00:01

【BZOJ 3036】 3036: 绿豆蛙的归宿 (概率DP)