用邻接矩阵存储图的dijkstra算法

 如果N过大邻接矩阵可能会爆

//o(n*n)且无法解决负权边 
#include<bits/stdc++.h>
using namespace std;
const int N=505;
int dist[N];//每个点到起点的距离
int g[N][N];//邻接矩阵
int n,m;
bool st[N];//存储已经确定的最短路径的点,也就是访问过了的
int dijkstra()
{
	//初始化每个点到起点的距离为无穷 
	memset(dist,0x3f3f3f3f,sizeof(dist)); 
	//1是起点
	dist[0]=0;
	//循环n次由此确定n个点到起点的最短距离
	for(int i=0;i<n;i++)
	{
		//每次用t来存没有确定最短距离且距离起点最近的点
		int t=-1;
		for(int j=0;j<n;j++)
		{
			if(!st[j]&&(t==-1||dist[j]<dist[t]))
				t=j;
		 }
		 st[t]=true;
		 //用这个点更新和他相连的点距离起点的距离
		 for(int j=0;j<n;j++)
		 	dist[j]=min(dist[j],dist[t]+g[t][j]); 
	 }
	 //如果n距离起点无穷,说明没有路径到达 
	 if(dist[n-1]==0x3f3f3f3f)return -1; 
	 return dist[n-1]; 
 } 
int main()
{
	cin>>n>>m;
	memset(g,0x3f,sizeof(g));
	while(m--)
	{
		int a,b,c;
		cin>>a>>b>>c;
		//防止重边 
		g[a][b]=min(g[a][b],c);
		g[b][a]=g[a][b];
	}
	int t=dijkstra();
	cout<<t<<endl;
	for(int i=0;i<n;i++)
	{
		cout<<dist[i]<<endl;
	}
	return 0; 
}

Dijkstra算法是一种用于解决单源最短路径问题的算法,可以用来计算从给定源节点到所有其他节点的最短路径。在邻接表存储的情况下,Dijkstra算法的时间复杂度为O((E+V)logV),其中E和V分别为边数和节点数。 当比较稠密时,邻接表存储的空间复杂度会比邻接矩阵低,但是在Dijkstra算法中,由于需要频繁地访问和更新距离数组,邻接表可能会导致大量的缓存不命中,从而降低算法的效率。 为了优化Dijkstra算法在邻接表存储下的性能,可以使用堆排序来维护节点的距离值,并且在每次更新节点距离值时,将新的节点插入堆中。这样就可以保证堆中的节点总是按照距离值从小到大排列,从而使得访问和更新距离数组的次数最小化。 具体地,可以使用一个小根堆来维护节点的距离值。首先将源节点的距离值设置为0,并将其插入堆中。然后,重复执行以下步骤,直到堆为空: 1.从堆中取出距离值最小的节点u; 2.遍历节点u的所有邻居节点v,如果从源节点到节点v的距离值可以通过节点u进行更新,则更新节点v的距离值,并将节点v插入堆中; 3.重复执行步骤1和步骤2,直到堆为空或者找到了目标节点。 在这个过程中,每个节点最多被插入堆一次,因此时间复杂度为O((E+V)logV)。 使用堆排序优化邻接表存储Dijkstra算法可以显著提高算法的效率,特别是在处理稠密的情况下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值