NOIP-模拟试题之--过路费

本文介绍了一道NOIP模拟试题,题目涉及农场中奶牛通行需支付的过路费问题。通过建立费用模型,求解奶牛从起点到终点的最小花费路径。文章提供了解题思路,包括利用Dijkstra算法和Floyd算法解决最大费用和次大费用情况,并给出了相应的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2018 NOIP 全套资料下载-提取码:072k

【问题描述】

为了发财,Mr_he在他的农场设置了一系列的规章制度,使得任何一只奶牛在农场中的道路行走,都要向他交过路费。
  农场中有 n 片草地(编号为1~n),并且有 m 条双向道路把这些草地连接起来。Mr_he已经在每条双向道路上设置一个过路费wi。可能有多条道路连接相同的两片草地,但是不存在一条道路连接一片草地和这片草地本身。最值得庆幸的是,奶牛从任意一片草地出发,经过一系列的路径,总是可以抵达其他任意一片草地。
  为了最大化自己的收入。Mr_he在每片草地上也设置了一个过路费用ci。并规定,奶牛从一片草地到另一片草地需要交纳的费用,是经过的所有道路的费用之和,加上经过的所有草地(包括起点和终点)的过路费的最大值。
  任劳任怨的牛们希望去调查一下,它们每一次的出行应该选择那条路径才能最节俭。她们要你写一个程序,接受 k 个问题并且输出每个询问对应的最小花费。第 i 个问题包含两个数字 s,t,表示起点和终点草地。

【输入格式】

第 1 行:三个用空格隔开的整数:n,m,k。
  第 2 到第 n+1 行:第 i+1 行包含一个单独的整数 c(1<=c<=100000),表示第 i 片草地的费用。
  第 n+2 行到第 n+m+1 行:第 j+n+1 行包含 3 个用空格隔开的整数:a,b,w(1<=a,b<=n,1<=w<=100000),表示一条道路(a,b)的费用为 w 。
  第 n+m+2 到第 n+m+k+1 行:第 i+n+m+1 行表示第 i 个问题,包含两个用空格隔开的整数 s 和 t(1<=s,t<=n 且 s!=t),表示一条询问的起点和终点。

【输出格式】

第 1 到第 k 行:第 i 行包含一个整数,表示从 s 到 t 的最小花费。

【输入样例】

5 7 3
2
5
3
3
4
1 2 3
1 3 2
2 5 3
5 3 1
5 4 1
2 4 3
3 4 4
1 3
1 4
2 3

【输出样例】

5
8
9

【样例解释】
。。不给!!!!(滑稽)

————————————————————————————————————————————————————
根据题目交代的路径费用的定义,可以想到枚举每一个点作为权值最大点的情况。这样就可以保证算出来的结果是正确的了(移动到这个最大点肯定是要用最短路啦)。但是显然每一组询问都去算的话是会超时的。面对10000组询问,可以想到打表。那么在知道这个点是最大值路径上的最大值并求出单源最短路之后怎么办呢?显然对于任意一条以点k为最大点值的点的路径i->j,可以拆分成i->k和k->j,那么就是说在这种情况下我们可以更新i->j的最小费用路径了。时间复杂度O(N*MlogN+N^3) ,已经可以AC,而且由于有剪枝条件的存在一般情况下达不到这个时间。

下面是dijkstra的代码:

#include< iostream>
#include< cstdio>
#include< cstring>
#include< cstdlib>
#include< algorithm>
#include< cmath>
#include< queue>
#include< set>
#include< map>
#include< vector>
#include< cctype>
#define inf 1e8+5
us

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值