zoukankan      html  css  js  c++  java
  • 2488 绿豆蛙的归宿

    提交次数:2

    难度:提高-

    涉及知识:拓扑排序/期望

    oj:codevs

    题目描述 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

     代码:

     1 #include<iostream>
     2 #include<vector>
     3 #include<queue>
     4 #include<cstdio>
     5 using namespace std;
     6 struct edge{
     7     int u, w;
     8     edge(int uu, int ww):u(uu), w(ww){}
     9 };
    10 vector<vector<edge> >v(100005);
    11 queue<int>q;
    12 int in[100005]; //每个点的入度 
    13 double p[100005]; //走到每个点的概率 Possibility 
    14 int n, m;
    15 double ans;
    16 
    17 int main(){
    18     int i;
    19     cin>>n>>m;
    20     for(i = 1; i <= m; i++){
    21         int a, b, c;
    22         cin>>a>>b>>c;
    23         v[a].push_back(edge(b, c));
    24         in[b]++;
    25     }
    26     q.push(1);
    27     p[1] = 1;
    28 while(!q.empty()){
    29         int node = q.front();
    30         q.pop();
    31         if(node == n) break;
    32         for(i = 0; i < v[node].size(); i++){
    33             int s = v[node].size();
    34             edge next = v[node][i];
    35             double k= double(p[node])/double(s);
    36             p[next.u] += k;
    37             in[next.u]--;
    38             ans += double(next.w)*k;
    39             if(in[next.u]==0){
    40                 q.push(next.u);
    41             } 
    42         }
    43     }
    44     printf("%.2lf
    ",ans);
    45     return 0;
    46 }

    备注:

    昨天上课时说到拓扑排序,老师随手在codevs上按题目分类搜的题(反正一共就两道),一道裸的拓扑排序。难点在于。。期望orz 最开始对这道题要求的期望完全理解错了

    第一次提交忘了改输出格式是输出两位小数。

    注意标黄的几行,改了好几次才改对,逻辑没弄清楚,现在梳理一下。

    扩展到一个点后计算到达这个点的概率p[i],方法是这个点原本的概率(因为也可能在之前从别的点扩展到它)+走到上一个点的概率p[node]/上一个点的出度,这时因为已经开始删边了,相当于已经走了那几条边,所以要算对ans的贡献,怎么算呢?

    边长*(走到上一个点的概率/上一个点的出度),这块似乎有点绕,但其实也很显然。走这条边的概率和走到这条边连的下一个点的概率没有直接关系(原因同上,点的概率要累加)

    这样看似乎就是一道很简单的题。。。以后要先想清楚再写,写完再改又废时间又有风险。。

  • 相关阅读:
    用于爬取知乎某个话题下的精华问题中所有回答的爬虫
    BSP -- 图书共享系统(Book Sharing Platform)
    【已解决】WPS2018 从第三页开始插入页眉页码(即前两页不要页眉页码)
    【编译原理】大白话讲解 First 集和 Follow 集的构造算法
    如果
    HTTP协议(1)------->资源和URL
    JavaWeb框架_Struts2_(八)----->Struts2的国际化
    深入理解java虚拟机----->垃圾收集器与内存分配策略(下)
    深入理解java虚拟机----->垃圾收集器与内存分配策略(上)
    JavaWeb框架_Struts2_(七)----->文件的上传和下载
  • 原文地址:https://www.cnblogs.com/fangziyuan/p/7017718.html
Copyright © 2011-2022 走看看