图的应用及经典算法-----最短路径算法合集----c语言

本文详细介绍了图论中的最短路径问题,包括定义、DFS、Floyd算法、Dijkstra算法和Bellman-Ford算法,以及SPFA优化算法。这些算法分别适用于不同的场景,如点到点、所有点到所有点的最短路径计算,并讨论了如何在C语言中实现。同时,还探讨了负权边的情况和判断负环的存在性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最短路径

在这里插入图片描述

定义

最短路径问题是图论研究中的一个经典算法问题, 旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。 算法具体的形式包括:
确定起点的最短路径问题 - 即已知起始结点,求最短路径的问题。

确定终点的最短路径问题 - 与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。

确定起点终点的最短路径问题 - 即已知起点和终点,求两结点之间的最短路径。
全局最短路径问题 - 求图中所有的最短路径。

求最短路径的算法

DFS----点到点

用深度优先遍历的方式求点到点的最短路径

//ibeg,iend的最小距离  现在到了icurr点  currpath现在已经经过了多长的距离 
void dfs_path(ALGraph *pg,int icurr,int iend,
	int *pminpath,int currpath,bool visited[]){
   
   
	if(icurr==iend){
   
   
		if(currpath < *pminpath){
   
   
			*pminpath = currpath;
		}
		return;
	}
	ArcNode *node = pg->vexs[icurr].firstarc;
	for(;node!=NULL;node=node->next){
   
   
		if(!visited[node->adjvex] && currpath + node->weight < *pminpath){
   
   
			visited[node->adjvex] = true;
			dfs_path(pg,node->adjvex,iend,pminpath,currpath+node->weight,visited);
			visited[node->adjvex] = false;
		}
	}
}
//求beg,end顶点的最短路径 
int dfs_min_path(ALGraph *pg,char beg,char end){
   
   
	int ibeg = graph_get_index(pg,beg);
	int iend = graph_get_index(pg,end);
	if(ibeg==-1||iend==-1)
		return -1;
	if(ibeg==iend)
		return 0;
	int minpath = MAX_INT;//记录最短路径的值 
	int currpath = 0; //找的过程中,经过的多长距离  
	bool visited[pg->vexnum];
	int i;
	for(i=0;i<pg->vexnum;i++)
		visited[i] = false;
	visited[ibeg] = true;	 
	dfs_path(pg,ibeg,iend,&minpath,0,visited);
	return minpath;
}

floyd—所有点到所有点

算法思想

通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。
从图的带权邻接矩阵A=[a(i,j)] n×n开始,递归地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。
采用松弛技术(松弛操作),对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3);

算法过程

1,从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。

2,对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短。如果是更新它。

把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G[i,j]=无穷大。定义一个矩阵D用来记录所插入点的信息,D[i,j]表示从Vi到Vj需要经过的点,初始化D[i,j]=j。把各个顶点插入图中,比较插点后的距离与原来的距离,G[i,j] = min( G[i,j], G[i,k]+G[k,j] ),如果G[i,j]的值变小,则D[i,j]=k。在G中包含有两点之间最短道路的信息,而在D中则包含了最短通路径的信息。

void floyd(ALGraph *
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HOVL_C++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值