之前已经写过朴素的Dijkstra了:
int Dijkstra(int x) {
int min, k;
for(int i=1; i<=n; i++) d[i] = a[x][i];
d[x] = 0;
InS[x] = true;
for(int i=1; i<=n-1; i++) {
min = 1e9;
for(int j=1; j<=n; j++)
if(min > d[j] && !InS[j])
min = d[k=j];
InS[k] = true;
for(int j=1; j<=n; j++)
if(d[j] > d[k]+a[k][j])
d[j] = d[k] + a[k][j];
}
for(int i=1; i<=n; i++) cout << d[i] << " ";
}
下面是基于vector数组的堆优化Dijkstra
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
struct Edge {
int from, to, dis;
Edge(int u, int v, int w) : from(u), to(v), dis(w) {}
};
struct HeapNode {
int d, u;
bool operator <(const HeapNode h) const {
return d > h.d;
}
};
#define MAXN 10010
struct Dijkstra {
int n, m;
vector<Edge> edges; //所有边
vector<int> G[MAXN]; //以i为起点的所有边
bool done[MAXN];
int d[MAXN];
int p[MAXN]; //记录上一条弧
void init(int n) {
this -> n = n;
for(int i=1; i<=n; i++) G[i].clear();
edges.clear();
}
void Add(int u, int v, int d) {
edges.push_back(Edge(u, v, d));
m = edges.size();
G[u].push_back(m-1);
}
void dijkstra(int s) {
priority_queue<HeapNode> Q;
for(int i=1; i<=n; i++) d[i] = 2147483647;
d[s] = 0;
memset(done, 0, sizeof(done));
Q.push((HeapNode) {
0, s
});
while(!Q.empty()) {
HeapNode x = Q.top();
Q.pop();
int u = x.u;
if(done[u]) continue;
done[u] = true;
for(int i=0; i<G[u].size(); i++) {
Edge e = edges[G[u][i]];
if(d[e.to] > d[u] + e.dis) {
d[e.to] = d[u] + e.dis;
p[e.to] = G[u][i]; //记录最短路径
Q.push((HeapNode) {
d[e.to], e.to
});
}
}
}
}
void Print_Path(int x) { //源点到x的最短路径
if(x == 0) return;
Print_Path(p[x]);
printf("%d ->", x);
}
} Dijk;
int main() {
int n, m, u, v, w, s;
scanf("%d%d%d", &n, &m, &s);
Dijk.init(n);
for(int i=1; i<=m; i++) {
scanf("%d%d%d", &u, &v, &w);
Dijk.Add(u, v, w);
}
Dijk.dijkstra(s);
for(int i=1; i<=n; i++) printf("%d ", Dijk.d[i]);
return 0;
}