https://labuladong.online/algo/data-structure/dijkstra-follow-up/#带限制的最短路径问题
https://labuladong.online/algo/problem-set/dijkstra/#_787-k-站中转内最便宜的航班
https://leetcode.cn/problems/path-with-maximum-probability/submissions/642501669/
用邻接表构建图
一、Dijkstra 算法核心思想
核心目标:找到从起点到图中所有其他节点的最短路径。
核心策略:贪心策略,每次选择距离起点最近且未确定最短路径的节点,然后用该节点更新其邻居的距离。
关键条件:所有边权值必须非负(否则可能导致算法失效)。
struct Node {
int u, k; // 节点和剩余换乘次数
int dist;
bool operator>(const Node& other) const {
return dist > other.dist;
}
};
priority_queue<Node, vector<Node>, greater<Node>> pq;
vector<vector<int>> dist(n, vector<int>(k+1, INF)); // dist[u][k]表示到达u且剩余k次换乘的最短距离
// 初始化起点
dist[start][k] = 0;
二叉堆
上面用到了很关键的优先队列。
二叉堆就是一种能够动态排序的数据结构。所谓动态排序,就是说我们可以不断往数据结构里面添加或删除元素,数据结构会自动调整元素的位置,使得我们可以有序地从数据结构中读取元素,这是一般的排序算法做不到的。
能动态排序的常用数据结构其实只有两个:一个是优先级队列(底层用二叉堆实现),另一个是二叉搜索树。
:
priority_queue<Type, Container, Compare> pq;
Type: 元素类型(如 int, string 等)
Container: 底层容器类型(默认为 vector
Compare: 比较函数/函数对象(默认为 less
// 默认大顶堆(最大元素优先)
priority_queue<int> max_heap;
// 小顶堆(最小元素优先)
priority_queue<int, vector<int>, greater<int>> min_heap;
// 自定义比较函数
struct Compare {
bool operator()(const pair<int, int>& a, const pair<int, int>& b) {
return a.second > b.second; // 按第二个元素升序
}
};
priority_queue<pair<int, int>, vector<pair<int, int>>, Compare> custom_pq;
浙公网安备 33010602011771号