在写出具体函数之前,需要先定义MAXV为最大顶点数、INF为一个很大的数字:
const int MAXV = 1000;
const int INF = 1000000000;
邻接矩阵版
int n, G[MAXV][MAXV];
int d[MAXV];
bool vis[MAXV] = { false };
void Dijkstra(int s) {
fill(d, d + MAXV, INF);
d[s] = 0;
for (int i = 0; i < n; i++) {
int u = -1, MIN = INF;
for (int j = 0; j < n; j++) {
if (vis[j] == false && d[j] < MIN) {
MIN = d[j];
u = j;
}
}
if (u == -1) return;
vis[u] = true;
for (int v = 0; v < n; v++) {
if (vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]) {
d[v] = d[u] + G[u][v];
}
}
}
}
从复杂度来看,主要是外层循环
O
(
V
)
O(V)
O(V)(V就是顶点个数n)与内层循环(寻找最小的d[u]需要
O
(
V
)
O(V)
O(V)、枚举v需要
O
(
V
)
O(V)
O(V)产生的,总复杂度为
O
(
V
?
(
V
+
V
)
)
=
O
(
V
2
)
O(V*(V+V))=O(V^2)
O(V?(V+V))=O(V2)。
邻接表版
struct Node
{
int v, dis;
};
vector<Node> Adj[MAXV];
int n;
int d[MAXV];
bool vis[MAXV] = { false };
void Dijkstra(int s) {
fill(d, d + MAXV, INF);
d[s] = 0;
for (int i = 0; i < n; i++) {
int u = -1, MIN = INF;
for (int j = 0; j < n; j++) {
if (vis[j] == false && d[j] < MIN) {
MIN = d[j];
u = j;
}
}
if (u == -1) return;
vis[u] = true;
for (int j = 0; j < Adj[u].size(); j++) {
int v = Adj[u][j].v;
if (vis[v] == false && d[u] + Adj[u][v].dis < d[v]) {
d[v] = d[u] + Adj[u][v].dis;
}
}
}
}
从复杂度来看,主要是外层循环
O
(
V
)
O(V)
O(V)与内层循环(寻找最小的d[u]需要
O
(
V
)
O(V)
O(V)、枚举v需要
O
(
A
d
j
[
u
]
.
s
i
z
e
)
O(Adj[u].size)
O(Adj[u].size)产生的。又由于对整个程序来说,枚举v的次数总共为
O
(
E
)
O(E)
O(E),因此总复杂度为
O
(
V
2
+
E
)
O(V^2+E)
O(V2+E)。
|