leetcode编程算法随笔(难度1854 Dijkstra )3650. 边反转的最小路径总成本
题目
https://leetcode.cn/problems/minimum-cost-path-with-edge-reversals/
给你一个包含 n 个节点的有向带权图,节点编号从 0 到 n - 1。同时给你一个数组 edges,其中 edges[i] = [ui, vi, wi] 表示一条从节点 ui 到节点 vi 的有向边,其成本为 wi。
每个节点 ui 都有一个 最多可使用一次 的开关:当你到达 ui 且尚未使用其开关时,你可以对其一条入边 vi → ui 激活开关,将该边反转为 ui → vi 并 立即 穿过它。
反转仅对那一次移动有效,使用反转边的成本为 2 * wi。
返回从节点 0 到达节点 n - 1 的 最小 总成本。如果无法到达,则返回 -1。
输入:n = 4, edges = [[0,1,3],[3,1,1],[2,3,4],[0,2,2]]
输出:5
解释:
#Dijkstra
#一般说D算法的主要思想是以贪心思路解决最短路径(边权和最小最大化)问题
#注意其中的细节就可以
#应试或者刷题的副作用很多,其一就是只记得套公式,却忘记公式的思想和来源以及其启发性, 所以先大概回忆一下Dijkstra算法的大概思路
首先明确的是,主要是解决图上的最短路径问题,因此点,连接点的边,边的权重,起始点,终点这几个基础是不可少的。变化的情况就具体情况具体分析。另外,一般情况下,边权非负也很重要,否则无限多的来回走负边,就让问题没有意义了。从基本点出发,从一个起始点,到一个终点,如果路径有很多,那么一条最短路会有什么特点?似乎,起点到这个路径上每一个点所选的路径数值都应该是最小的,贪心的感觉就来了~路径 s->...->x->... ->e 是 最短路径那么 s->...->x 就应该是 s到x的最短路径,否则,选择一条比当前s到x路径更短的路径,保持x到e 不变,就可以得到一个条更短的路径。如果所有途径的中间点x 都解决了,是不是有点动态规划的感觉?如果想,因为路径不确定,所以没法知道哪些点是途径点,似乎问题就卡住了,换方向,换角度 ,这里应该有很多思路,其中一个可能是这样的s-> a -> ... -> x -> .. ->ea 作为路径上的第一个点,是所有与s 直接相连的点中,路径最短的点吗?但是呢,如果能发现从s到a的距离也不可能再小了,就会很有用s不可能通过走其它点,绕路走向a 而是的路径数值更小#可以概括为将比较粗略(抽象)的思路,具体一下,可能会看出点什么~a与s 放到一起考虑,会如何?它们有什么共同点吗?这很难的样子,但是假如它们是一个整体了,那么新加入的与这个整体距离最近的点,有什么特点?新加入的点,无论是与哪个点连入这个整体,从s到它的距离都不能更小了# 如同动态规划里常常会假定一个状态或者子问题已解决一样。在简单的版本里,可以通过遍历,来找到距离当前整体距离最近的点x。在优化的版本里,则使用堆。每次加入一个新的点进入整体,就将与该点连接的点遍历一下,加入到堆。比如当a 被加入后,遍历与a相连接的点,加入与原整体相邻元素的堆中,注意度量方式,是与这个整体(集合)的距离。#可以总结为,考虑特点的时候,尝试从不同性质,或将该元素放入不同的集合,# 这里好像很有点打哪里指向哪里的感觉!但应该比只是去套公式好一些到了这一步,基本上就可以写代码了。呃,这个题目,还有个小的弯弯绕,做一些分析,可以知道,还是Dijkstra的方式解决