数据结构——最短路径之Dijkstra算法(与最小生成树的prime算法很像,建议一起看)

本文介绍了Dijkstra算法,用于解决单源最短路径问题,特别是在非负权值边的情况下。算法思想包括初始化邻接矩阵,通过不断找到未访问且距离源点最近的顶点进行路径更新。文章通过与Prime算法的对比,帮助读者理解Dijkstra算法的工作原理,并提供了AcWing 849题目的实例和朴素实现。
摘要由CSDN通过智能技术生成

最短路径之Dijkstra算法
(一)Dijkstra算法

单源最短路径:就是从某一个顶点出发,到图中任意顶点之间的最短路径;

【算法概述】:Dijkstra算法适用于解决单源最短路径的问题。即:从源点到任意指定顶点之间的最短距离的问题;但Dijkstra算法要求所有边的权值非负。看过Prime算法的同学都知道,Dijkstra算法与Prime算法很相似,不同的就是dis数组的更新方式。Dijkstra算法用邻接矩阵存图比较方便。

【算法思想】:先用一个数组记录从源点到图中个顶点直接相连的距离,如果不直接连,就记录为无穷大,然后通过对该数组的更新,使得dis[x]表示从源点到x的最短路径;

1.1 初始化

用邻接矩阵来存图,先进行初始化,自己到自己的距离初始化为0,到另外的顶点的距离初始化为无穷大。并将标记数组都置为0,表示所有顶点都未访问;

void init(){
   
	for(int i=0;i<nodeNum;i++){
   
		for(int j=0;j<nodeNum;j++){
   
			if(i==j)
				matrix[i][j]=0;
			else
				matrix[i][j]=INF;
		} 
	}
	memset(visited,0,sizeof(visited));	
}

1.2 Dijkstra主体
参数st表示源点,此题是0
第一步:先用min_distance数组储存与0直接相连的顶点之间的距离。并标记0号顶点;然后用一个while死循环来变量所有顶点,最坏的情况就是遍历所有顶点。
第二步:就是在当前的min_distance数组里找一个顶点没有访问过且距离源点最近的点,记录它的顶点下标;
第三步:更新min_distance数组:如果x顶点没有被访问,并且0到x顶点的距离(直接或间接)大于上面min_distance数组最小值加上点p到x点的距离,就对min_distance数组更新: min_distance[x] = min + matrix[p][x];(可以理解为:从源点直接到某点的距离大于间接到某点的距离
第四步:重复上面的第二步和第三步;
图示:
第一步:此时的dis数组:0 5 2 7;并标记源点0;此时的vis数组:1 0 0 0

void Dijkstra(int start){
   
	//第一个结点进入,标记已走过 
	for(int i=0;i<nodeNum;i++){
   
		min_distance[i]=matrix[start][i];
	}
	/*for(int i=0;i<nodeNum;i++){
		cout<<min_distance[i];
	}*/
	visited[start]=true;//表示start结点已经走过
	
	
	
	
	while(true){
   
		//找到距离这个结点最近的节点的坐标 
		int min=INF;
		int index=-1;
		for(int i=0;i<nodeNum;i++){
   
			if(visited[i]==false && min_distance[i]<min){
   
				min=min_distance[i];//从起点到index的最小距离 
				index=i;
			}
		}
		visited[index]=true;//标记已经访问
		if(index==-1)//此时所有的节点都已经访问过了 
			bre
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值