• 【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

    【分析】

      这题题意绝对有问题!

    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
    ",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
    ",f[1]);
    52     return 0;
    53 }
    View Code

    【醉了。。。

    2017-04-22 11:00:01

  • 相关阅读:
    C#基础知识系列十(集合)
    C#基础知识系列九(对IEnumerable和IEnumerator接口的糊涂认识)
    C#基础知识系列八(const和readonly关键字)
    C#基础知识系列七(base、this、new、override、abstract、virtual、static)
    C#基础知识系列六(静态类和静态类成员)
    C#基础知识系列五(构造函数)
    C#基础知识系列四(运算符汇总)
    C#基础知识系列三(类和结构体、String和StringBuilder、equals和==)
    C#基础知识系列二(值类型和引用类型、可空类型、堆和栈、装箱和拆箱)
    C#基础知识系列一(goto、i++、三元运算符、ref和out、String和string、重载运算符)
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6747180.html
Copyright © 2020-2023  润新知