#include <queue>
#include <utility>
class Solution {
public:
/*
从起点开始,不断选择 当前距离最短且未访问 的节点,把它的邻居的距离更新成更短的值,直到所有节点都确定了最短距离。
创建邻接表->创建最短距离表、是否遍历过表->创建小根堆->初始化小根堆->循环:提取对顶,更新边能到的节点离起点的最近距离;直到堆为空;
*/
int findShortestPath(int n, int m, vector<vector<int> >& graph) {
//邻接表:行号表示起点,pair就是到节点和距离;
vector< vector< pair<int, int>>> adj(n + 1);
//初始化邻接表
for (auto g : graph) {
int i = g[0]; //起点
int v = g[1]; //终点
int w = g[2]; //距离
adj[i].push_back(make_pair(v, w)); //加入邻接表
}
//D杰斯特算法:从起点开始,遍历每个边,更新边能到达的节点的最短距离,对更新了的节点遍历,遍历过了就不用遍历了;
const int INF = 1e9;
vector<int> dist(n + 1, INF); //表示从1到i的最短距离,还没有确认最短
vector<bool> vis(n + 1,
false); //vis[i]表示已经遍历过了此节点为起点的边
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>>
pq; //小根堆,存放0到u的目前为止的最短距离,用来遍历节点的下一个边
dist[1] = 0;
pq.push({0, 1});
while (!pq.empty()) {
auto [d, u] = pq.top();
pq.pop(); //对这个节点,遍历下边
if (vis[u]) {
continue;
} else {
vis[u] = true;
}
for (auto& edge : adj[u]) { //对以u开头的边遍历,更新
int w = edge.second; //距离
int v = edge.first; //下一个节点
if (dist[v] > w + d) {
dist[v] = d + w; //更新0到v的最短距离
pq.push({dist[v], v}); //对到v的最短距离
}
}
}
// 初始化
return dist[n] == INF ? -1 : dist[n];
}
};