• Luogu4316 | 绿豆蛙的归宿 (期望DP)


    题目背景

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

    题目描述

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

    输入格式

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

    输出格式

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

    输入 #1

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

    输出 #1

    7.00

    说明/提示

    对于20%的数据 N<=100

    对于40%的数据 N<=1000

    对于60%的数据 N<=10000

    对于100%的数据 N<=100000,M<=2*N

    —————————————————————————————————————

    图套期望DP入门题,考虑到整张图是一个有向DAG,可以直接使用递归或者拓扑排序进行状态转移。

    状态转移方程:$ F[i] = sum F[j] / siz $

    其中 $ i -> j $ 有一条有向边,(siz)(i)的出度

    递归的边界为当前节点为n节点或者是已经计算用的节点(基于DAG的性质可以直接return)

    可以写出代码:

    #include <bits/stdc++.h>
    #define MAXN 100007
    using namespace std;
    struct Edge { int t,w; };
    vector<Edge> G[MAXN];
    int n,m;
    double f[MAXN];
    inline void dfs(int u) {
    	//printf("u = %d
    ",u);
    	if (u==n || f[u]!=0) return;
    	int k=(int)G[u].size();
    	for (int i=0;i<(int)G[u].size();i++) {
    		int v=G[u][i].t,w=G[u][i].w;
    		dfs(v),f[u]+=(w+f[v])/k;
    	}
    	//printf("%d -> %.2lf
    ",u,f[u]);
    }
    inline int read() {
    	int w=0,X=0; char ch=0;
    	while (!isdigit(ch)) w|=ch=='-',ch=getchar();
    	while (isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    	return w?-X:X; 
    }
    int main() {
    	n=read(),m=read();
    	for (int i=1;i<=m;i++) {
    		int a=read(),b=read(),c=read();
    		G[a].push_back((Edge){b,c});
    	}
    	dfs(1),printf("%.2lf",f[1]);
    	return 0;
    } 
    
  • 相关阅读:
    Curl Get请求&漏参数
    【Java基础】日期操作(返回当前日期&日期比较)
    【Java基础】生产者消费者模式
    [Groovy] 在Groovy中优雅的实现do while
    【转载】时间复杂度的度量
    [转载]Spring Cloud初探
    [Maven] 使用Maven管理多模块项目
    JS基础三
    JS基础部分(二)
    笔记不详细记录了,学完css之后做出下面分布的导航页
  • 原文地址:https://www.cnblogs.com/zhwer/p/12024839.html
Copyright © 2020-2023  润新知