• [题解] [LuoguP4316] 绿豆蛙的归宿


    [题解] [LuoguP4316] 绿豆蛙的归宿

    一.前言

    ​ 今天本着停课不停学的决心,看了看数学期望。结果是 见不熟悉之数学起身慌而走之。话虽然这么说,但是例题还是要做的,题解也是要写的。凭本人小学水平数学,粗略的理解数学期望就是操作的足够多了之后趋于平均的一个?的东西。,嘛,就相当于骰子扔多了平均值就会趋于一个常数,但是怎么都不会扔出7就对了。(此处为古贺朋绘酱默哀qwq,永远都做不出自己想要的梦我永远喜欢古贺朋绘

    二.题意简述

    ​ 说了一个大点的废话以后,进入这一篇的正题。

    题意:在一个有向无环图中,给出各边的信息,求从起点走到终点的路径长度期望。(顺带一提选择每条边的概率是一样的)

    三.思路

    ​ 那么知道了题意之后,很明显的这是个DP。(别问我怎么看出来的问就无效性),那么我们设置 从 i 点到终点的路径长度期望为 (f[i]) ,当前 i 的出度为 (out[i]) ,选中的边所对的点为 v ,边的长度为 (dis(i,v)),就可以得出递推式。

    [f[i]=frac{sum (f[v]+dis(i,v))}{out[i]} ]

    ε=(´ο`*)))为什么是这样呢?首先为了平均要除以一个出度是没有问题的(毕竟从终点往前推,同时这里实现的时候可以用分配律搞搞),然后由于是路径长所以是加而不是乘。(不知道这样讲能不能看懂),然后边界条件是 (f[n]=0).(显然)

    ​ 虽然说起来是DP,但是实际的应用是DFS,毕竟在图上又要遍历,之类的。

    四.CODE

    const int MAXN=200005;
    int n,m;
    int head[MAXN],ne[MAXN],to[MAXN],dis[MAXN],tot,out[MAXN];
    inline void add(int x,int y,int z){
    	to[++tot]=y;
    	ne[tot]=head[x];
    	head[x]=tot;
    	dis[tot]=z;
    }
    double f[MAXN];
    bool vis[MAXN];
    void dfs(int x){
    	if(x==n){
    		f[x]=0;
    		return ;
    	}
    	if(vis[x])return;
    	vis[x]=1;
    	for(int i=head[x];i;i=ne[i]){
    		int v=to[i];
    		dfs(v);
    		f[x]+=(f[v]+1.0*dis[i])/out[x];
    	}
    }
    int main(){
    n=read();m=read();
    m_for(i,1,m){
    	int x=read(),y=read(),z=read();
    	add(x,y,z);
    	out[x]++;
    }
    dfs(1);
    printf("%.2f",f[1]);
    return 0;
    }
    

    五.后记

    ​ 其实由于某种奇奇怪怪的原因,好像可以先拓扑一下路径再操作,会快一些(大概)

  • 相关阅读:
    Oracle-函数
    Oracle-存储过程
    Linux-文件系统概述
    Oralce-PL/SQL编程-游标
    Oracle -操作数据库
    Oralce常用系统函数
    SQL语言基础-基本概念
    Linux-进程管理
    Linux-用户管理
    shell里的IFS内置环境变量
  • 原文地址:https://www.cnblogs.com/clockwhite/p/12344383.html
Copyright © 2020-2023  润新知