用途:
计算一个图中源点到其它所有点的最短路径。
算法描述:
- 将图的所有顶点分成两个集合,S集合与T集合。其中,S集合包含了已经求出最短路径的所有顶点,T集合包含了其余顶点。初始化时,S集合仅包含起始点v0.
- 遍历T集合中的所有顶点,找到与起始点距离最小的点,将其加入到S集合。
- 更新dis[]数组。dis数组存储起始点到其余各顶点的最短距离。
- 重复2,3步骤,直到S中包含了图的所有顶点。
算法流程:
- 集合S = {1},当前结点v = 2。
dis[2] = 2
dis[3] = 3
dis[4] = 6
dis[5] = 4
dis[6] = MAX - 集合S = {1,2},当前结点v = 3。
dis[2] = 2
dis[3] = 3
dis[4] = 6
dis[5] = 4
dis[6] = MAX - 集合S = {1,2,3},当前结点v = 5。
dis[2] = 2
dis[3] = 3
dis[4] = 6
dis[5] = 4
dis[6] = 6 - 集合S = {1,2,3,5},当前结点v = 4。
dis[2] = 2
dis[3] = 3
dis[4] = 6
dis[5] = 4
dis[6] = 6 - 集合S = {1,2,3,5,4},当前结点v = 6。
dis[2] = 2
dis[3] = 3
dis[4] = 6
dis[5] = 4
dis[6] = 6 - 集合S = {1,2,3,5,4,6},程序结束
代码如下:
#include <iostream>
#include <string.h>
using namespace std;
#define MAXNUM 100
#define MAXDIS 100000
int arcs[MAXNUM][MAXNUM]; //图的邻接矩阵
int S[MAXNUM]; //表示当前节点是否在S中,s[i] = 1:当前结点在S中;s[i] = 0:当前结点不在S中
int pre[MAXNUM]; //存储最短路径
int dis[MAXNUM]; //起点到当前结点的最短路径
void Dijkstra(int v0, int n);
int main()
{
int n = 0;
int v0 = 0; //起点
cin>>n;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
cin>>arcs[i][j];
}
}
Dijkstra(v0,n);
for(int i = 1; i < n; i++)
{
if(i == v0)continue;
cout<<v0<<"->"<<i<<' '<<dis[i]<<endl;
}
return 0;
}
void Dijkstra(int v0, int n)
{
int min = 0;
int v = 0;
for(int i = 0; i < n; i++) //初始化
{
S[i] = 0; //开始,所有节点都不在集合S中
dis[i] = arcs[v0][i]; //最短距离初始化
if(dis[i] < MAXDIS)
{
pre[i] = v0;
}
else
{
pre[i] = -1;
}
}
S[v0] = 1; //把起始点加入到S集合中
for(int i = 0; i < n; i++)
{
min = MAXDIS;
for(int j = 0; j < n; j++) //找与起始点相连的所有顶点的距离最小值
{
if(!S[j]) //顶点j不在集合S中
{
if(dis[j] < min)
{
v = j;
min = dis[j];
}
}
}
S[v] = 1; //将找到的距离最小的点加入到集合S中
for(int j = 0; j < n; j++) //将V加入S后,更新当前的距离信息
{
if(!S[j] && min + arcs[v][j] < dis[j])
{
dis[j] = min + arcs[v][j];
pre[j] = v;
}
}
}
}