Dijkstra算法
Dijkstra 算法是基于贪心思想的,建立在有向有权图之上的,使用了广度优先搜索解决带权有向图或者无向图的单源最短路径问题,并且它要求不能存在负权边。
算法步骤:
- 将所有的顶点分为两部分:已知最短距离的顶点和未知最短距离的顶点。初始化时,已知最短距离的顶点只有起点。
- 从当前尚未确定最短距离的所有点中,找到距离起点最短的点 x,标记为已访问,即把 x 放入
- 松弛操作:通过点 x 更新其他所有点距离起点的最短距离
- 如果所有点都已经求出了距起点的最短距离,则结束;否则,返回步骤2
代码实现:
具体实现时,一种思路是用邻接矩阵
来表示有向有权图。用 dist 数组来存储当前所有点距离起点的最短距离,用 visited 数组来标记顶点是否已经确定了最短距离。
朴素Dijkstra + 邻接矩阵
/*
Author: ZL
Description: Dijkstra
Date: 2021-8-17
*/
#include <bits/stdc++.h>
#define Inf INT_MAX / 2
using namespace std;
std::vector<std::vector<int>> graph = { {0 , 1 , 12 , Inf, Inf, Inf},
{Inf, 0 , 9 , 3 , Inf, Inf},
{Inf, Inf, 0 , Inf , 5, Inf},
{Inf, Inf, 4 , 0 , 13 , 15 },
{Inf, Inf, Inf, Inf, 0 , 4 },
{Inf, Inf, Inf, Inf, Inf, 0 }
};
std::vector<int> result;
void Dijkstra(int index) { //传入起点的编号
int n = graph.size();
std::vector<int> dist(n, Inf);
for (int i = 0; i < n; ++i) {
dist[i] = graph[index][i]; //初始化dist
}
std::vector<bool> visited(n, false); //用于判断顶点是否已经确定最短距离
visited[index] = true;
int cnt = 1; //已经确定了最短距离的顶点的数量
while (cnt < n) {
int minDist = Inf;
int minIndex; //表示每轮距离起点最近的点的下标
//取出最近的那个点的下标
for (int i = 0; i < n; ++i) {
if (!visited[i] && dist[i] < minDist) {
minDist = dist[i];
minIndex = i;
}
}
visited[minIndex] = true; //标记为已访问
cnt++;
//松弛操作,把刚才取出的最近那个的点作为中转点,更新距离
for (int i = 0; i < n; ++i) {
dist[i] = min(dist[i], dist[minIndex] + graph[minIndex][i]);
}
}
result = dist;
}
int main() {
Dijkstra(0);
for (auto r : result) {
cout << r << " " ;
}
cout << endl;
system("pause");
return 0;
}