题目链接
题目大意
一辆卡车从起点s到终点t,走的是最短路径。强盗从r出发前往卡车途经的某个点拦截,同样,强盗选择最近的点。卡车走的最短路径可能有多条,求最坏情况下强盗花费的时间。
简而言之,两个步骤:
1)求r点到(所有s到t的)最短路的最短距离;
2)在这些最短距离中找最大值。
这样子,本问题即最小值最大化问题,与上一篇的思路是类似的。
解决本题,主要有两个部分:
1)求r点到其他各点的最短距离;
2)二分法找出最大值。
第二点的具体思路:二分法跑s和t之间的最短路,如果发现某点v到r的最短距离distr[v]小于等于mid,那么就不把v点加入松弛队列。
现做出下列解释:
首先,我们已经求得r到其他各点的最短距离distr,并先对s,f跑一次最短路,得到s到f的最短路径为ans。
接下来是二分,如图所示,假设s到f有5条最短路径,由于最多有n个点,所以答案的范围是0到n,现在对0到n二分。
我们可以简单地把这个过程比做是猜数字。
一开始,B心里默念了一个数字:5,然后让A来猜,范围是0到6。
A:我猜这个数字是3
B:小了
于是A知道这个数一定在4和6之间。
类比过来,一开始我们猜mid = 3;但是此时是大了还是小了,需要我们自己判断,如何判断呢?只需要对s到f跑一次最短路,当distr[v]<=mid时,不把v加入松弛队列,于是这一次v1、v2、v3都不会加入松弛队列,但是由于经过v4、v5的路也是最短路,所以求得的s到f的最短路dist[f]仍然等于ans,如此一来,我们知道存在比mid还大的答案,亦即mid偏小了,于是令left=mid+1,继续二分;
这一次,A说:我猜这个数是5;
B卖了个关子:这次不偏小
不