单源最短路(优先队列优化的dijkstra算法):PIPI的逃跑路线Ⅲ

单源最短路(优先队列优化的dijkstra算法):PIPI的逃跑路线Ⅲ

问题:

在这里插入图片描述
在这里插入图片描述

思路:

  本题为单源最短路问题,麻烦点在于边权会不断变化,乍一看好似非常难,我们不可能每次去更新变化后的边权,仔细观察发现边权的变化函数f(x) = 1 / (1 - x)有点特殊,是有意设计成这样的,那么一定蕴含某个规律。设某条边的权值为x,经过一条道路后,权值变为1 / (1 - x),那么再经过一条道路后呢?权值将变为f(f(x)) = 1 / (1 - 1 / (1 - x) ) = (x - 1) / x,不妨再试试,再经过一条道路后,权值变为f(f(f(x))) = 1 / (1 - (x - 1) / x) = x,权值又变回了x,即权值的变化处于一个循环中:
在这里插入图片描述
  当我们发现这个边权变化函数的秘密,这个题目就很好求解了,其边权只有三种可能。
  所以我们在bfs时设定一个步数step:当step%3=0,两点距离就是最原始的值w;当step%3=1,两点距离变为|1/(1-w)|,由于w都是大于1的,所以也就是1/(w-1);当step%3=2,两点距离变为|1-1/w|,1减去一个小数,其值肯定大于零,所以也就是1-1/w。于是我们开个dis[3][]的数组(dis[i][j]表示,step%3为i时,源点到达j点的最短距离 ),跑一遍最短路即可。

需注意的点

  • 我们每次将节点Node置入优先队列,Node除了包含节点编号,源点到该点的距离外,还需要包含源点到该点走的步数 % 3的值,步数信息应包含在结点中,而不是在bfs中修改
  • 设step表示当前遍历的结点的步数信息,distance表示源点到该点的距离,weight表示该点到邻接点的距离,nextNode.index表示邻接点的编号,那么进行更新最短距离的判断为weight + distance < dis[(step + 1) % 3][nextNode.index],注意dis数组的第一个索引为(step + 1) % 3,而不是step,因为从当前遍历点走到其邻接点,步数需加1

代码:

import java.util.*;

public class Main {
   
    static final double INF = 1000000000000000000.0 + 7;
    static Queue<Node> q = new PriorityQueue<>();
    static double[][] dis = new double[3][100002];
    static List<Node>[] adj = new ArrayList[100002];
    public static void main(String[] args
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

happy19991001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值