图的单源最短路径——Dijkstra算法

单源最短路径——Dijkstra算法

指定一个点到其余各个顶点的最短路径

算法核心

Dijkstra算法是通过一个dis数组,存储指定顶点到所有顶点的初始路径

此失的初始路径成为“估计值”,因为该路径是否最短未知

通过寻找离指定点最近的顶点i为起点,寻找以该顶点到其它顶点的距离是否比指定点直接到其它顶点的距离短,以此来“松弛”路径,并更新dis(i)数组的值为确定的最短路径

以此类推,当所有估计值转换为确定值时,问题解决

此方法在未做任何优化下时间复杂度O(n方)

代码

#include <iostream>
using namespace std;

int main()
{
	//book[i] = 0表示i点处于估计值,1表示i点处于确定值 
	int e[11][11],dis[11],book[11]={0};
	int inf = 99999999;
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i == j){
				e[i][j] = 0;
			}else{
				e[i][j] = inf;
			}
		}
	}
	int a,b,c;
	for(int i=0;i<m;i++){
		cin>>a>>b>>c;
		e[a][b] = c;
	}
	//初始dis数组 
	for(int i=1;i<=n;i++){
		dis[i] = e[1][i];
	}
	
	//从顶点1开始寻找所有顶点离1的最短路径
	book[1] = 1; 
	
	//Dijkstra算法核心部分 
	for(int i=1;i<=n-1;i++){
		//找到离1顶点最近的顶点
		int min = inf;
		int u;
		for(int j=1;j<=n;j++){
			if(book[j] == 0 && dis[j] < min){
				min = dis[j];
				u = j;
			}
		} 
		//标记为确认点 
		book[u] = 1;
		//根据此点的出边来寻找从1到该点所有出边的最短路径
		for(int j=1;j<=n;j++){ 
			if(e[u][j] < inf){
				if(dis[j] > dis[u] + e[u][j]){
					dis[j] = dis[u] + e[u][j];
				}
			}
		}
	}
	
	for(int i=1;i<=n;i++){
		cout<<dis[i]<<" ";
	}
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
离字典,将起始节点的距离设为0,其他节点的距离设为无穷大 distances = {node: sys.maxsize for node in graph} distances[start] = 0 # 初始化已访问节点的集合和未访以下是使用问节点D的集ijkstra合 visited = set() unvisited算法求解最短路径的Python = set(graph) while unvisited: # 代码示例: ```python class D选择当前ijkstra距: def __init__(self, graph离最小的节点 , start, current goal): self.graph = graph # 邻接表_node = min(unvisited, key=lambda self node: distances[node]) # 更新.start = start当前节点的 # 起邻居节点点 self.goal =的距离 goal # 终点 for neighbor in graph self.open[current_node]: _list = {} if neighbor in # open 表 self.closed_list unvisited: new_distance = distances[current_node] + = {} graph[current_node][neighbor # closed 表 self.open_list[start] if new_distance] = < distances[neighbor]: 0.0 # 将 distances[neighbor] = new_distance # 将当前起点放入 open_list 中 self.parent = {节点标记start:为已访 None} 问,并从未访问集合中移除 visited.add # 存储节点的父子系。键为(current_node) 子节点, unvisited值为父.remove(current_node) return节点。方便做最 distances def print后_path(dist路径的ances,回 start溯 self.min, end): _dis = None # 根 # 最短路径的长度 def shortest_path据距离字典和终点节点(self): while True: ,逆向 if self打印路径.open_list is path = [end None: ] print('搜索 current_node =失败 end while current_node !=, 结束!') break distance start: , min_node = for neighbor in graph min(zip[current_node]: if(self.open_list distances[current.values(), self_node] ==.open_list.keys distances[neighbor())) #] + graph 取出距[neighbor][current_node]: 离最小的节点 self path.open_list.pop.append(min_node)(neighbor) current_node = neighbor break path.reverse() # 将其从 open_list 中去除 self print.closed("_list[minShortest_node] = path from", distance # 将节点加入 closed start, "to", end,_list ":", "->".join(path)) # 示例 中 if min_node == self.goal: # 如果节点为的邻接矩阵终点 self.min_dis = distance 表示 graph shortest = { _path = [ 'Aself.goal]': {'B': # 5, 'C 记录从': 终1}, 点回溯的路径 'B
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值