主要分为五部分
- 邻接矩阵版
- 主函数
- 普通邻接表版
- vector版
- 优先队列版
算法思想:每次选出dis最小的那个点i,则dis[i]必定为为顶点s到顶点i的最短距离
更新所有与i相邻的顶点的dis值
依据:如果存在一条i到j的最短路径,其经过的节点为(i……k,j)。那么(i……k)的这条路径也必然是i到k的最短路径。
每个版本的最初都是构建图,首先将图初始化,然后进行加边。对于双向图要注意双向加边。最后进行dijkstra算法,详情请看主函数。
dijkstra算法伪代码:
清除所有点的标记
设dis[s] = 0;其它d[i]为无穷大
循环N次
{
在所有未标记结点中,选出dis值最小的节点x;
给结点x标记
对所有从x出发的边(x,y)进行更新
}
本文注意要点:所有版本接口相同,节点编号均从0开始。
/***************************
//邻接矩阵版dijkstra算法
***************************/
#define INF 0x3F3F3F3F //把INF(最大值)设置成0x3f3f3f3f
const int MAXN = 1010; //所开数组大小可以修改,一般情况1010足够
int G[MAXN][MAXN]; //G[a][b]表示a,b的权值,G[][]二维数组为构建的邻接矩阵
int vis[MAXN]; //vis[a]记录是否已经查看过'a'点vis[a] == 1 表示已经查看过改点
int dis[MAXN]; //dis[a]记录从起点到'a'点之间的最短路径
//初始化函数,应该在加第一条边之前进行初始化
void init(int n){//n表示gongyoun个点
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
G[i][j] = INF; //初始时假设各不连通,G[i][j]设置为INF 注:把INF 设置成 0x3f3f3f3f
}
}
//加边处理,加第一条边前初始化,加边完成后再进入dijksrea函数
void add_edge(int u,int v,int d){
G[u][v] = min(G[u][v],d); //更新u,v边上的权值,并将权值最小的存入G[u][v]||不是最新的值而是最小的
}
//上面的工作是为了构建图init()为初始化图
// dijkstra算法函数 至此前期工作必须已经完成,开始求从某点出发的最短路径
void dijkstra(int s,int n){ //s 表示从s点出发的最短路径
//初始化vis[],dis[],不可以放到init()函数中,当需要在一张图中求从多点出发时,需多次跑dij,每次跑都需要对dis,vis数组初始化
for(int