图论——最短路——算法(3.0)

本文介绍了最短路径算法,包括Floyd算法、未优化与优化后的Dijkstra算法、单源负权的Ford算法以及SPFA算法。Floyd算法适用于多元最短路径问题,Dijkstra算法适用于单源最短路径,其优化版时间复杂度为O((m+n)logn)。Ford算法处理单源负权路径,而SPFA是对Ford算法的队列优化,用于处理负权重边的情况。
摘要由CSDN通过智能技术生成

最短路算法:

  1. floyd算法
  2. Dijkstra算法
  3. Dijkstra算法(堆优化)
  4. ford算法
  5. spfa算法(ford算法的队列优化)

一、只有5行代码的floyd算法:

1、 什么是floyd算法

弗洛伊德算法是解决多元最短路径的算法(什么是多源, 顾名思义就是起点有多个, 跑完floyd算法就算出以每个顶点做起点到各个点的最短路径)。

2、时间复杂度 O(n^3), 空间复杂度O(n^2)
3、适用性:
			1、多源最短路
			2、带负权值的
			优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。
			缺点:时间复杂度比较高,不适合计算大量数据。
4、代码实现

flody算法是从中间结点的角度来考虑的

for(k = 0;k < n;k++)
	for(i = 0;i< n;i++)
		for(j = 0;j <n;j++)
			if(grap[i][k]!=inf&&grap[k][j]!=inf&&grap[i][j] > grap[i][k]+grap[k][j])
				 grap[i][j] = grap[i][k]+grap[k][j];

floyd算法用到的是动态规划算法。
动规公式: grap[i][j] = min(gtap[i][j], grap[i][k]+grap[k][j]).

对于floyd的证明:

floyd的证明

二、单源最短路径的Dijkstra算法(未用堆排优化):

1、什么是Dijkstra
2、时间复杂度O(n^2):
		为优化的时间复杂度:外循环n-1次, 内循环 2*n次 , 所以时间复杂度 O((n-1)(2*n))近似 O(n^2)
3、适用性:
		1、单源最短路径
		2、不带负权值的边
4、代码实现:

对于dijkstra我一般喜欢用邻接矩阵, 邻接表储存图

(1)实现代码1
/**********

原理

每次 通过 未使用的点中,距起点最近的那个点 去松弛其他点的距离  (其实就 用近点(从最近开始, 然后是第二近...) 松弛远的点, 本质就是贪心思想)

所以dijkstra 时间复杂度主要跟点的个数有关

***********/
#include<bits/stdc++.h>
#define inf 0x3f3f3f
using namespace std;
int G[1111][1111];// 邻接矩阵 ,  也可以用邻接表
int n; //图中点的个数

void Dijkstra(int s, int d)// s 起点 , 终点
{
   
	int i;
	int dis[1111];// 存s到  其他各点的距离

	/**初始化距离**/
	for(i = 1;i <= n;i++) dis[i] = inf;// 到其他点的距离为无限大
	dis[s] = 0; //初始化到自己为1

	/***标记数组初始化****/
	int book[1111];//标记数组,标记该点是否使用 
	memset(book, 0 , sizeof(book));//初始化 0表示未使用


	for(i = 1;i <= n-1;i++)// 循环 n-1 次, 最远的那个点(就是距离 起点 第n近的点(这里第1近的点是起点自己)肯定不能松弛其他店)
	{
   
		
		/**********找点过程**********/
		int u = -1;//-1 u表示未使用的点中,距起点最近的那个点,初始化z最近点的编号为 -1
		int Min = inf;// 初始化 未使用的点中,距起点最近的那个点到起点的距离为 inf
		for(int j = 1;j <= n;j++)
		{
   
			if(book[j] == 0&& dis[j] < Min)//寻找未使用的点中,距起点最近的那个顶点
			{
   
				Min = dis[j];
				u 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值