码迷,mamicode.com
首页 > 其他好文 > 详细

2488 绿豆蛙的归宿

时间:2017-06-10 12:38:18      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:href   wrapper   efi   个数   double   toggle   pre   mda   tac   

codevs——2488 绿豆蛙的归宿

 

 时间限制: 1 s
 空间限制: 64000 KB
 题目等级 : 黄金 Gold
 
 
 
题目描述 Description

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

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

输入描述 Input Description

  第一行: 两个整数 N M,代表图中有N个点、M条边

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

输出描述 Output Description

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

样例输入 Sample Input

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

样例输出 Sample Output

7.00

数据范围及提示 Data Size & Hint

  对于20%的数据   N<=100
  对于40%的数据   N<=1000
  对于60%的数据   N<=10000
  对于100%的数据  N<=100000,M<=2*N

 

来源:Nescafe 19

分类标签 Tags 点此展开 

 
 
思路:
这个题说是概率dp,但是只用一个完美的拓扑排序完全就可以过。
其实这道题概率dp完全可以过,大佬们可以尝试一下,不懂的可以看这位大佬的博客
蒟蒻由于不会概率dp就只好用拓扑排序水过了。。。。
我们下面来说说拓扑排序的思路。
我们现在输入的时候与处理出每一个点的入度和初度。有人肯定要问了:处理出入度和出度有什么用啊??
这里我们用入读是来得知这个点是否应该被用拓扑排序删掉这个点。(在拓扑排序中有用就对了)
我们用一个点的出度来判断一一条路径被走的概率。(用该点的概率*该点出度的个数即为走这条边的概率)
然后我们在用一个数组储存每一条路径的概率。由于期望值是可以累加的,期望值等于这个点的边权乘这个点的概率。
这样我们就可以在最后时用每一条边的概率乘上这条边的边权。这样累加起来就是整条路径的期望值。
代码:
 
#include<stack>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 10000
using namespace std;
stack<double>q;
int n,m,x,y,z,tot;
double p[N],ans;
int in[N],out[N],head[N];
struct Edge
{
    int from,to,dis,next;
    double gl;
} edge[N<<2];
void add(int x,int y,int z)
{
    tot++;
    edge[tot].to=y;
    edge[tot].dis=z;
    edge[tot].next=head[x];
    head[x]=tot;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            in[y]++;
            out[x]++;
        }
    p[1]=1;
    q.push(1);
    int now;
    while(!q.empty())
        {
            now=q.top();
            q.pop();
            for(int i=head[now]; i; i=edge[i].next)
                {
                    p[edge[i].to]+=p[now]*1.0/out[now];
                    edge[i].gl=p[now]*1.0/out[now];
                    in[edge[i].to]--;
                    if(!in[edge[i].to]) q.push(edge[i].to);
                }
        }
    for(int i=1;i<=m;i++) ans+=edge[i].gl*edge[i].dis;
    printf("%.2lf",ans);
    return 0;
}

2488 绿豆蛙的归宿

标签:href   wrapper   efi   个数   double   toggle   pre   mda   tac   

原文地址:http://www.cnblogs.com/z360/p/6973996.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!