Dijkstra 算法是对SPFA算法的优化,将普通的队列改为关于距离的优先队列。好处是一旦某个元素出列,这个元素的最短距离已经正确,无需再次入列。
算法描述:
不再将相邻点编号加入队列,而是将相邻点的编号和距离都加入队列,每次出列距离最小的点
模板:
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
int n, m, s;
int dis[100010], vis[100010];//visit存是否已经出列
vector<pii> g[100010];
priority_queue<pii, vector<pii>, greater<pii> > q;
void dijk() {
q.push(make_pair(0, s));
dis[s] = 0;
while (!q.empty()) {
int now = q.top().second;
q.pop();
if (vis[now]) {//如果已经出列,则跳过
continue;
}
vis[now] = 1;//标记now 已经出列
for (auto to : g[now]) {
int v = to.second, w = to.first;
if (dis[now] + w < dis[v]) {//如果找到更短距离
dis[v] = dis[now] + w; //则更新
q.push({dis[v], v});//被更新点要入列
}
}
}
return;
}
int main() {
scanf("%d%d%d", &n, &m, &s);
int u, v, w;
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &u, &v, &w);
g[u].push_back({w, v});//与spfa不同,dijk要反着存以便比较的时候先比权值
}
memset(dis, 0x3f, sizeof(dis));
dijk();
for (int i = 1; i <= n; i++) {
printf("%d%c", dis[i], (i == n) ? '\n' : ' ');
}
return 0;
}