如果搜索到距离更近的点,就要更新这一点的距离,但是不一定需要将其放入优先队列中,因此需要一个判重数组st,检测该点是否是最近的点。
未优化版:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 150010, INF = 0x3f3f3f3f;
int e[N], ne[N], w[N], h[N], idx;
int d[N];
void add(int x, int y, int z) {
e[idx] = y;
ne[idx] = h[x];
w[idx] = z;
h[x] = idx;
idx++;
}
void dijkstra() {
memset(d, 0x3f, sizeof d);
d[1] = 0;
priority_queue<PII> heap;
heap.push({ 0, 1 });
while (heap.size()) {
PII t = heap.top();
heap.pop();
int dist = t.first, ver = t.second;
for (int i = h[ver]; i != -1; i = ne[i]) {
if (d[e[i]] > dist + w[i]) {
d[e[i]] = dist + w[i];
heap.push({ d[e[i]], e[i] });
}
}
}
}
int main() {
memset(h, -1, sizeof h);
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++) {
int x, y, z;
cin >> x >> y >> z;
add(x, y, z);
}
dijkstra();
if (d[n] == INF) {
cout << -1;
}
else {
cout << d[n];
}
return 0;
}
优化版:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 150010, INF = 0x3f3f3f3f;
int e[N], ne[N], w[N], h[N], idx;
int d[N];
bool st[N];
void add(int x, int y, int z) {
e[idx] = y;
ne[idx] = h[x];
w[idx] = z;
h[x] = idx;
idx++;
}
void dijkstra() {
memset(d, 0x3f, sizeof d);
d[1] = 0;
priority_queue<PII, vector<PII>, greater<PII> > heap;
heap.push({ 0, 1 });
while (heap.size()) {
PII t = heap.top();
heap.pop();
int dist = t.first, ver = t.second;
if (st[ver]) {
continue;
}
st[ver] = true;
for (int i = h[ver]; i != -1; i = ne[i]) {
if (d[e[i]] > dist + w[i]) {
d[e[i]] = dist + w[i];
if (!st[e[i]]) {
heap.push({ d[e[i]], e[i] });
}
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
memset(h, -1, sizeof h);
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++) {
int x, y, z;
cin >> x >> y >> z;
add(x, y, z);
}
dijkstra();
if (d[n] == INF) {
cout << -1;
}
else {
cout << d[n];
}
return 0;
}
确实类似于搜索BFS,不过bfs也是基于dij算法 bfs只不过是边权都为1 更新的时候不需要找到最小值 因为都一样嘛 不过也可以理解为最小值 还有一个类似的算法是双端队列广搜 他只有0 1这两种权值因此只需一个双端队列就可以维护 单调性
我感觉是 每次确定一个点的最短路然后扩展与他相连的点 更新这些点的最短路 然后都放到堆里 找到更新过的这些点的最小值 然后出对 这个点的最小值就确定了 然后再标记 表示这个点已经被确定 然后重复上述步骤 直到确定完所有点
引用你说的”我感觉是 每次确定一个点的最短路然后扩展与他相连的点 更新这些点的最短路 【然后都放到堆里】”。我认为应该是“更新这些点的最短路,然后【不一定】都要放入堆里”。你的想法和就是我写的【未优化版】的dijkstra算法。