计算最短路径的基础算法,Dijkstra算法基础模板
const int inf = 0x3f3f3f3f;
const int maxn = 1050;
struct Edge {
int from, to, dist;
Edge(int f, int t, int d) :from(f), to(t), dist(d) {}
};
struct HeapNode {
int d, u;
HeapNode(int dd, int uu) :d(dd), u(uu) {}
bool operator < (const HeapNode& rhs) const {
return d > rhs.d;
}
};
struct Dijkstra {
int n, m; //点数和边数
vector<Edge> edges; //边列表
vector<int> g[maxn];//每个结点出发的边编号(从0开始)
bool done[maxn]; //是否永久标号
int d[maxn]; //s到各个点的距离
int p[maxn]; //最短路中的上一条边
void init(int n) {
this->n = n;
for (int i = 0; i < n; ++i) g[i].clear(); //清空邻接表
edges.clear(); //清空边表
}
void add(int from, int to, int dist) { //如果是无向图,每次加边调用两次
edges.push_back(Edge(from, to, dist));
m = edges.size();
g[from].push_back(m - 1);
}
void dijkstra(int s) { //s为源点
priority_queue<HeapNode> que;
for (int i = 0; i < n; ++i) d[i] = inf;
d[s] = 0;
memset(done, 0, sizeof(done));
que.push(HeapNode(0, s));
while (!que.empty()) {
HeapNode x = que.top();
que.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.dist) {
d[e.to] = d[u] + e.dist;
p[e.to] = g[u][i];
que.push(HeapNode(d[e.to], e.to));
}
}
}
}
};
测试程序
#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1050;
struct Edge {
int from, to, dist;
Edge(int f, int t, int d) :from(f), to(t), dist(d) {}
};
struct HeapNode {
int d, u;
HeapNode(int dd, int uu) :d(dd), u(uu) {}
bool operator < (const HeapNode& rhs) const {
return d > rhs.d;
}
};
struct Dijkstra {
int n, m; //点数和边数
vector<Edge> edges; //边列表
vector<int> g[maxn];//每个结点出发的边编号(从0开始)
bool done[maxn]; //是否永久标号
int d[maxn]; //s到各个点的距离
int p[maxn]; //最短路中的上一条边
void init(int n) {
this->n = n;
for (int i = 0; i < n; ++i) g[i].clear(); //清空邻接表
edges.clear(); //清空边表
}
void add(int from, int to, int dist) { //如果是无向图,每次加边调用两次
edges.push_back(Edge(from, to, dist));
m = edges.size();
g[from].push_back(m - 1);
}
void dijkstra(int s) { //s为源点
priority_queue<HeapNode> que;
for (int i = 0; i < n; ++i) d[i] = inf;
d[s] = 0;
memset(done, 0, sizeof(done));
que.push(HeapNode(0, s));
while (!que.empty()) {
HeapNode x = que.top();
que.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.dist) {
d[e.to] = d[u] + e.dist;
p[e.to] = g[u][i];
que.push(HeapNode(d[e.to], e.to));
}
}
}
}
};
int n, m, s;
Dijkstra dij;
void print(int x) {//递归打印以x为终点的最短路径
if (x == s) {
printf("%d", x);
return;
}
Edge& e = dij.edges[dij.p[x]];
print(e.from);
printf(" %d", x);
}
int main() {
while (scanf("%d%d%d", &n, &m, &s) == 3) {
dij.init(n);
for (int i = 0; i < m; ++i) {
int from, to, dist;
scanf("%d%d%d", &from, &to, &dist);
dij.add(from, to, dist);
dij.add(to, from, dist);
}
dij.dijkstra(s);
for (int i = 0; i < n; ++i) {
if (i == s) continue;
printf("到点%d的最短路径:", i);
print(i);
printf(" 总长度:%d\n", dij.d[i]);
}
}
return 0;
}
/*
5 7 0
0 1 100
0 2 30
0 4 10
2 1 60
2 3 60
3 1 10
4 3 50
*/