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;