算法分析与设计实践-作业2-2-用Dijkstra算法解决最短路问题

用Dijkstra算法解决最短路问题

1.问题

对于下图使用Dijkstra算法求由顶点a到顶点h的最短路径。

2.解析

若设1号点(a点)为起点,求长度为n的数组d,其中d[i]表示从起点到节点i的最短路径的长度。那么顶点a到顶点h的最短距离即为d[n]。
Dijkstra算法的流程如下:

  1. 初始化d[1]=0,其余节点的d数组的值为无穷大。
  2. 找出一个未被标记的、d[x]最小的节点x,然后标记节点x
  3. 扫描节点x的所有出边(x,y,z),若d[y]>d[x]+z,则使用d[x]+z,更新d[y]。
  4. 重复上述2,3两个步骤,直到所有节点都被标记。

Dijkstra算法基于贪心思想,它只适用于所有边的长度都为非负数的图。当边长z都是负数时,全局最小值不可能再被其他节点更新,故在之前选出的节点x必然满足:d[x]已经是起点到x的最短路径。我们不断选择全局最小值进行标记和扩展,最终可得到起点1到每个节点的最短路径的长度。

3.设计

void dijkstra(){
    
    
	memset(d,0x3f,sizeof(d));
	memset(v,0,sizeof(v));//节点标记 
	//默认起点为1号顶点 
	d[1]=0;
	for(i form 1 to n-1){
    
    
		int x=0;
		//找到未标记节点中dist最小的 
		for(j form 1 to n){
    
    
			if(!v[j]&&(x==0||d[j]<d[x])){
    
    
				x=j;
			}
		}
		v[x]=1;
		//用全局最小值点x更新其他节点 
		for(y form 1 to n){
    
    
			d[y]=min(d[y],d[x]+a[x][y]);
		}
	}
}

4.分析

时间复杂度分析:设n个顶点,m条边。

  1. 初始化d[1]=0,其余节点的d数组的值为无穷大:O(n)
  2. 找出一个未被标记的、d[x]最小的节点x,然后标记节点x,扫描节点x的所有出边(x,y,z),若d[y]>d[x]+z,则使用d[x]+z,更新d[y],不断重复该步骤,直到所有节点都被标记:O(n^2)

综上所述,Dijkstra算法的时间复杂度为O(n^2)。

5.源码

https://github.com/lu-225/As-before/blob/master/2018212212124%20%E9%99%86%E5%AE%B6%E8%BE%89%20%E5%AE%9E%E9%AA%8C2-2/Dijkstra.cpp

猜你喜欢

转载自blog.csdn.net/qq_43633353/article/details/104761670
今日推荐