朴素版的思路如下:
定义一个集合s表示点到源点的最短距离,每次寻找一个不在s中并且到源点距离最短的点vec,用这个点到源点的距离来更新其他的点。
上述思路的伪代码为:
while n:
t ;
for i 1-n:
if i 不在 s :
t = i
更新s, s[t]标记
for i 1-n:
dis[i] = min dis[i], dis[t]+g[t][i];
朴素算法的伪代码不能完全表示出整个dijkstra的细节(也就是整个算法的具体写法要比实际多运行一点,因为寻找不在集合中的点浪费了时间),堆优化版本缩短了时间并且展示了dijkstra的细节
int dijkstra(int u) {
dist[u] = 0;
priority_queue<PII, vector<PII>, greater<PII> > heap;
heap.push({0, 1});
while(heap.size()) {
auto t = heap.top();
heap.pop();
int vec = t.second, distance = t.first;
if(st[vec]) continue;
st[vec] = true;
for (int i = h[vec]; i != -1; i = ne[i]) {
int to = e[i];
if(dist[to] > distance+w[i]) {
dist[to] = distance+w[i];
heap.push({dist[to], to});
}
}
}
if(dist[n] == inf) return -1;
return dist[n];
}
上述代码展示了如下细节:
- 查找s集合中的点最快的实现方法可以达到log的复杂度
- 找到这个点后,标记
- 用这个点更新其他点的距离,并且将更新后的距离及点入队列,再从队列中找到最短的距离的点。