迪杰斯特拉单源点最短路径算法
从起始点开始,采用贪心算法的策略,
每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。
#include<iostream>
#include<vector>
using namespace std;
/*
6
0 0 10 0 30 100
0 0 5 0 0 0
0 0 0 50 0 0
0 0 0 0 0 10
0 0 0 20 0 60
0 0 0 0 0 0
5
0 10 0 0 5
0 0 1 0 2
0 0 0 4 0
7 0 6 0 0
0 3 9 2 0
从起始点开始,采用贪心算法的策略,
每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。
*/
const int inf = 1e9;
int main()
{
int n;
cin >> n;
vector<vector<int>> map(n, vector<int>(n));
for (auto& x : map)
{
for (auto& a : x)
{
cin >> a;
if (a == 0)
a = inf;
}
}
for (auto& x : map)
{
for (auto& a : x)
cout<< a<<" ";
cout << '\n';
}
vector<bool> final(n);//标记是否已找到最短路径
vector<int> dist(n,inf);//最短路径长度
vector<int> path(n,-1);//路径上的前驱
/*
* Dijkstra算法:单元点最短路径
* 从结点0出发,进行扩展,在dist上找到最小的距离,此节点的前去就是节点0
* 再进行以刚才最短路径的结点来作为源点继续扩展
*/
int cnt = 1;//已被访问结点
int begin = 0;//起点为0
final[0] = true;//标记起点已访问
path[0] = -1;
dist[0] = 0;
for (int i = 0; i < n; ++i)
{
if (!final[i]&&map[begin][i] > 0)
{
dist[i] = map[begin][i];
path[i] = begin;
}
}//初始化起点数据
while (1)
{
int min_pos = -1;
for (int i = 0; i < n; ++i)
{
if (!final[i] && (min_pos == -1 || dist[i] < dist[min_pos]))
{
min_pos = i;
}
}
begin = min_pos;
final[min_pos] = true;//结点min_pos的最短路径找到
cnt++;
if (cnt == n)//所有节点都扩展了,break
break;
for (int i = 0; i < n; i++)
{
if (!final[i]&&dist[i] > dist[begin] + map[begin][i])
{//如果当前有节点的新路径距离小于之前的路径,更新该节点的dist和path
dist[i] = dist[begin] + map[begin][i];
path[i] = begin;//更新该节点的前驱
}
}
}
cout << "dist[" << n << "] = ";
for (auto x : dist)
cout << x << " " ;
cout << endl;
cout << "path[" << n << "] = ";
for (auto x : path)
cout << x << " ";
cout << endl;
return 0;
}
总结:
算法理解不难,要初始化的条件很多,最后输出的结果页不明显