洛谷P4316

news/2025/3/6 22:57:21/文章来源:https://www.cnblogs.com/wzj20101105/p/18756714

[P4316 - 绿豆蛙的归宿](P4316 绿豆蛙的归宿 - 洛谷)

题意解读

题目描述

给出张 n 个点 m 条边的有向无环图,起点为 1,终点为 n,每条边都有一个长度,并且从起点出发能够到达所有的点,所有的点也都能够到达终点。

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

那么我们可以从题目中读出以下信息:

  • 这是一个DAG(有向无环图),也就是说我们每次路径的选择都是无后效性的,因为没有任何一条路径可以到达我们自己的节点

    以下是一个DAG的示例

![屏幕截图 2025-03-06 221428](C:\Users\Administrator\Desktop\屏幕截图 2025-03-06 221428.jpg)

  • 这是一道有关于期望的问题,也就是说我们需要一定的数学知识去解决这道题。
  • 由于出现了1/k这个系数,所以我们可能需要考虑小数的情况。

分析

那么在题意解读中我们分析出来了两个关键信息:

  • 无后效性
  • 有关于期望

那么我们自然想到了期望DP的方式去解决这个问题。

那么我们按照以下步骤设计DP

确定状态

划分阶段-根据阶段确定求解顺序

决策选择-动态转移方程

边界条件-起点设置

求解目标

确定状态

首先我们来解释一下期望到底是个什么东西。

假设现在在图上有三个点A,B,C,且这个图是一个DAG

两条路径可以从A->C:

  • A->B->C : 6
  • A->C : 4

那么我们从A->C的期望值就是(6 + 4) / 2 = 5,即这个公式:

设有n条路径,每条路径的长度为ln:
$$
(l_1+l_2+l_3+...+l_n) / n
$$
由于这是一个期望DP,所以我们开始的时候一定要建反图,也就是把整个DAG反过来:

g[v].push_back({u , w});
cnt[u]++;//出度
ind[u]++;//入度

那么我们的初始化就完成了。

那么来到我们的第二个问题:

f[x]存的到底是啥?

为了方便后续的编码,我们将f[x]存储的信息表示为x->n的所有期望路径总长。

划分阶段

我们来确定一下这个问题的求解顺序:

  • 存图 - 存一个反图,并且将入度(ind)和出度(cnt)初始化完毕
  • 拓补排序 - 由于这个问题求解的是在DAG上的最短路径,所以我们需要一个top_sort来完成这个任务
  • 在拓补排序中设计DP公式 - 根据期望路径长度的计算公式将DP状态转移公式设计完毕
  • 输出排序后的f[1] - 此时f[1]就是最终答案

根据这个第四步发表一下我自己的看法:

其实如果是单纯的对这个f进行排序的话完全可以用一个priority_queue<int , vector<int> , greater<int> > q来完成,因为优先队列天然有序

状态转移方程

我们深入浅出的来解释这个问题,先上公式:
$$
f[v] = 1 * cnt[v] / (w + f[u])
$$
分部解释。

  • f[v] , f[u]分别表示什么 : u,v表示的都是节点编号,其中u是v的前驱节点,f[v]表示的信息为v->n的所有期望路径总长。

  • 为什么要乘上cnt[v] : 证明如下:
    $$
    E(y)= p_1x_1+p_2x_2 +...+p_nx_n \
    E(x)= p_1(x_1 + w) + p_2(x_2 + w) +...+p_n(x_n + w) = E(y)+ \sum_i^np_i*w = E(y) + w
    $$

以上证明为数学证明。

根据以上信息我们得出了状态转移公式:f[v] += 1.0 / cnt[v] * (w + f[u])

由于我们只是单纯的计算期望长度,没有十分复杂的决策管理,又因为边权为正,所以我们拓补排序计算出来的答案一定是最优解。

起点设置

这个我觉得不需要太多的解释,题目已经规定起点为1,终点为n了

求解目标

Code

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'#define TRACE 1
#define tcout TRACE && cout#define fst ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);#define int long longconst int INF = 0x3f3f3f3f3f3f3f3f;
const int P = 998244353;
const int N = 1e6 + 10, M = 2e6 + 10;
int n,m;
vector<pair<int , int> > g[N];
int ind[N];//入度 
int cnt[N];//出度 
double f[N];
void top_sort()//拓补排序
{queue<int> q;q.push(n);f[n] = 0;while(!q.empty()){auto u = q.front();q.pop();for(auto [v , w] : g[u]){f[v] += 1.0 / cnt[v] * (w + f[u]);ind[v]--;if(ind[v] == 0){q.push(v);//若入度归零,说明这条路走完了}}}
}
signed main()
{cin >> n >> m;for(int i = 1;i <= m;i++){int u,v,w;cin >> u >> v >> w;g[v].push_back({u , w});//邻接表存图cnt[u]++;ind[u]++;}top_sort();cout << fixed << setprecision(2);cout << f[1] << endl;return 0;
}

记录详情 - 洛谷 | 计算机科学教育新生态

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/894862.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

fastadmin + workman 实现websocket前后端通信http

1.安装workman扩展composer require workerman/workerman2.安装think-workercomposer require topthink/think-worker=1.0.* 3.如果在windows下使用,还需下载composer require workerman/workerman-for-win4.根目录创建server.php 。用来启动服务#!/usr/bin/env php <?php…

日报202536

继续学习了Springboot,感觉有点麻烦:User package com.xxx.demo1.pojo;public class User {String id;String name;@Overridepublic String toString() {return "User{" +"id=" + id + \ +", name=" + name + \ +};}public String getId() {re…

[JLOI2014] 路径龟划

传送门 我的部落格 貌似没有比较通俗介绍红绿灯期望介绍方法的?我来一发不需要积分基础能看懂的严谨证明~ 题目大意 这道题 luogu 题面不太清晰,大意给定一张无向图,你需要开车从起点走到终点,有些点会设红绿灯,给出每个红绿灯的红灯时间和绿灯时间,你见到红绿灯时红绿灯…

Vue 脚手架发展

Vue 脚手架是一个基于 Vue.js 进行快速开发的完整系统,Vue 脚手架致力于将 Vue 生态中的工具基础标准化。Vue 的工具链 CLI(通常指 @vue/cli)与 create-vue 是 Vue 生态中两个不同的脚手架工具,它们在功能定位、技术栈和适用场景上有显著区别。 Vue CLI(@vue/cli) Vue CL…

18C++循环结构-多重循环(1)

1、循环的嵌套; 2、双重循环的应用一、循环的嵌套 问题:#include <iostream> using namespace std; int main() {int j;for(j=1;j<=5;j++)cout<<*;return 0; }再编一程序,每次输出3行,每行5个"*"号。 在外层加一个循环语句来实现;流程图如:#inc…

Mybatis-plus01--快速开始

前言 在编写Java开发过程中,尤其是CRUD开发,我们会发现大部分事件都在编写Java持久层的增删改查上了,并且配置mybatis的mapper文件也是一件麻烦的事。如果你也有这样的烦劳,看来就可以认识一下我们的新朋友mybatis-plus了。 MyBatis-Plus 是一个 Mybatis的增强工具,在 MyB…

作业二:文本查重

作业介绍这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023github https://github.com/Ryon-h/3123003446这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/SoftwareEngineeringClassof2023/homework/13324这个作业的目标 完成…

上哪儿下载stable diffusion

要在本地环境中下载和安装Stable Diffusion,您可以遵循以下几种方法: 方法一:GitHub源码下载(工作流下载:https://www.mix688.com/964.html)硬件与软件环境准备:确保计算机配备至少4GB显存的NVIDIA GPU。安装Windows操作系统。准备大约10GB的硬盘空间。安装所需软件:下…

清华大学DeepSeek课程:基于DeepSeek的AI音乐词曲创作法(附视频下载)

本课程由清华大学新媒沈阳团队精心打造,旨在教授大家如何利用DeepSeek这一强大的AI工具进行音乐词曲创作。DeepSeek不仅能够帮助我们理解音乐创作的基本原理,还能激发我们的创造力。本课程由清华大学新媒沈阳团队精心打造,旨在教授大家如何利用DeepSeek这一强大的AI工具进行…

2024 年中国大学生程序设计竞赛全国邀请赛(郑州)暨第六届 CCPC 河南省大学生程序设计竞赛(Problem L. Toxel 与 PCPC II)

对于这道题我最开始是想用斜率优化dp,但是x是四次方明显不行,如果是二次方就好了,所以要换一个思路, 可以观察到如果一次性修复的x太多了,会导致时间消耗太大,这样我们还不如一个错误一个错误的修,当x=22时x的四次方就超过了200000,所以说我们最多一次修复22个bug了,值…

2025.3.3微服务架构(Dubbo)

Dubbo配置方式 1.注解: 基于注解可以快速的将程序配置,无需多余的配置信息,包含提供者和消费者。弊端是根据配置信息无法快速定位。XML:和Spring做结合,相关的Service和Reference均使用Spring集成后的。通过这样的方式可以很方便的通过几个文件进行管理整个集群配置。可以快…