学习来源:计蒜客
1.Dijkstra算法定义
迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。
2.代码
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
//定义一个较大的整形数
const int INF = 0x3f3f3f3f;
//边的定义,vertex:边的另外一个端点,weight:边的权值
struct Edge {
int vertex, weight;
};
class Graph {
private:
int n; //顶点个数
vector<Edge> * edges; //邻接表
bool * visited; //记录是否访问过了
public:
int * dist; //这个用于保存从起点出发,到每个点的距离
Graph (int input_n) {
n = input_n;
edges = new vector<Edge>[n];
dist = new int[n];
visited = new bool[n];
memset(visited, 0, n);
memset(dist, 0x3f, n * sizeof(int));
}
~Graph() {
delete[] dist;
delete[] edges;
delete[] visited;
}
void insert(int x, int y, int weight) {
Edge edge1,edge2;
<span style="white-space:pre"> </span>edge1.vertex = x;
<span style="white-space:pre"> </span>edge1.weight = weight;
<span style="white-space:pre"> </span>edge2.vertex = y;
<span style="white-space:pre"> </span>edge2.weight = weight;
<span style="white-space:pre"> </span>edges[x].push_back(edge2);
<span style="white-space:pre"> </span>edges[y].push_back(edge1);
}
void dijkstra(int v) {
dist[v] = 0;
//外层循环是要找起点到n个顶点的最短路径
for (int i = 0; i < n; i++) {
int min_dist = INF, min_vertex;
//循环从未访问结点中,从起点出发,距离起点最近的点
//因为这里的dist是起点到每个顶点的距离
for (int j = 0; j < n; j++) {
//未访问且小于上一个记录最短距离(因为第一次循环后,除了起点旁边的顶点的dist被更新为权值,其他的还是大整数,以下图为例,这里i=1时,<span style="font-family: Arial, Helvetica, sans-serif;">min_vertex 应该是l</span>)
if (!visited[j] && dist[j] < min_dist) {
min_dist = dist[j];
min_vertex = j;
}
}
//标记为已访问
visited[min_vertex] = 1;
//其实就是更新当前min_vertex这个编号的点的周围结点的dist为最小的权值
for(Edge &j : edges[min_vertex]){
//当i=0时,就是第一次循环时,min_vertex就是下图的a点,下面就是更新a,e的距离为10,a,l的距离为5
//而当i=1,min_vertex是下图的l点,min_dist = 5, j第一个遍历到e,min_dist + j.weight = 5 + 3 = 8 < 10 = dist[j.vertex]
//所以更新起点a到e的最短距离
if (min_dist + j.weight < dist[j.vertex]) {
dist[j.vertex] = min_dist + j.weight;
}
}
}
}
};
int main() {
int n, m;
cin >> n >> m;
Graph g(n);
for (int i = 0; i < m; i++) {
int a, b, c;
cin >> a >> b >> c;
g.insert(a, b, c);
}
//调用算法,起点到各点的最短路径都储存在数组中,下面将数组输出
g.dijkstra(0);
for (int i = 0; i < n; i++) {
cout << i << ": " << g.dist[i] << endl;
}
return 0;
}
环境:C++11
运行结果:
输入:
输出: