Travel [BFS]

20 篇文章 0 订阅
13 篇文章 0 订阅

Travel [BFS]

话说这道题并没有找到提交的地方…就不写代码了[滑稽]

题目描述

给定一张n 个点的完全图,边都是无向的。

一共有n(n−1)/2 条边,其中有m 条边的边权是a,剩下的边边权都是b。

求1 到n 的最短路。

数据范围

2 ≤ n ≤ 100000; 0 ≤ m ≤ 500000

题解

一 初步分析

这是一张完全图,也就是说任意两点之间必有一条路相连。

如果 Len[1>n]==a L e n [ 1 − > n ] == a ,那么最短路里面肯定不能再包含 a a ,即Lena

同理可得 Len[1>n]==b L e n [ 1 − > n ] == b 的情况。

所以最短路一定只包含 a a b

现在只用把含 a a 和含b的边单独提出来跑最短路,并在两个答案里面取最小值即可。

二 如何跑最短路

对于第一张图(边权全部为 a a 的图),边数并不是很多,O(m)时间复杂度内就可以BFS跑完。(dijkstra的时间复杂度是 (n+m)log n ( n + m ) l o g   n

对于第二张图(边权全部为 b b 的图),显然不能够直接用BFS跑。

我们考虑BFS的执行过程:BFS是把队列中的每一个点延伸出去的边依次讨论,并把没在队列中的点加入队中,很多时间浪费在了没有用的边上。实际上,这么多条边里面最多只有n条边是有用的,也就是说,每个点只需要入队一次。如果避免了重复进队的点和无用的边,就可以快速找出最短路。

现在的任务是,精确地找出连向最短路的点

由分析可得,边权为 b b 的边(简称b边)最多会被分为 m m 个部分(考虑从一个点辐射状发出的边中,有m a a 边,剩余的全是b边;其余情况同样如此)(当有 a a 边相邻时,b边会被分为 <m < m <script type="math/tex" id="MathJax-Element-49">

这里写图片描述

我们给每条边编号(没有特别的顺序)。

设一个 b b 边的区间为[L,R] fa[i] f a [ i ] 表示编号>=i,且不在队列中的最小编号。初始时 fa[i]=i f a [ i ] = i ,类似于并查集。注意:这与并查集中 fa[i] f a [ i ] 的定义有所不同。

按照边的编号顺序,对每一个区间进行如下操作:

  1. int x=getfa(L);

  2. while(x<=R){x入队; 进行最短路的操作; fa[x]=x+1; x=getfa(x+1);}

    I. fa[x]=x+1是因为x+1尚未入队。

    II. 最后一句表示的是x往后跳。精确地找出在最短路上的点。

然后我们就可以愉快地得出第二张图的最短路了。

最后比较两张图的答案,输出最小值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值