C++学习第六篇——最短路

最短路是图论最重要的算法之一,也是算法难点。经过这篇的学习,你会发现你离成功就差一个最短路的距离。=.=
最短路是指,某个点到某个点之间的距离最短。

算法1:Dijkstra算法

迪杰斯特拉算法是很典型的单源最短路算法,而且时间复杂度较其他算法更低,唯一的缺点是无法判断含负权边的图的最短路。而且其仅能作为单源最短路,也就是一个起点、一个终点求最短。在开始前推荐大家先去看我的另一篇博客最小生成树其中的prim算法和这个很类似。
同样由于技术有限,仅靠文字和代码讲解。-_-

int pic[1005][1005];//存图 

在输入之前,初始化图,将各点之间的距离设置为最大值,表示无法到达。
这里的图是单向的。

void init()
{
	for(int i=0;i<1005;i++)
	{
		for(int j=0;j<1005;j++)
		{
			pic[i][j]=(1<<21);//最大值可以自己设定,只要能表示不可达即可
		}
	}
}

dijkstra模板函数如下
特别强调c++和java不同,新开的数组会沿用之前相同名字的内存地址,所以赋值false很关键。之前我的模板错误在此
另外注意起点下标0-n-1或者1-n需要更改

void dijkstra()
{
	int weight[1005];//起始到其他端点的值 
	bool visit[1005];
	for(int i=0;i<n;i++)
	{
		weight[i]=pic[0][i];//将图中0到各个端点的值赋给weight数组 
		visit[i]=false;
	}
	weight[0]=0;
	visit[0]=true;
	//此时起点为0
	while(true)//0点作为起始点,从下一个点开始 
	{
		int j=0,k=-1,min=(1<<21);
//weight内的值为0时表示,已经访问过 
//遍历weight数组,寻找一个最小值,并且该点没有被访问过 
		while(j<n)
		{
			if(min>weight[j]&&!visit[j])
			{
				min=weight[j];
				k=j;//用k存下这个节点 
			}
			j++;
		} 
//已知的min是我当前起始节点到k节点的距离,已知连接边中最短的 
		if(k==-1) break;
		visit[k]=true;//访问过该节点 
//自此形成从起始到K的边,将其连接
 		for(int m=0;m<n;m++)
		{
		 	if(weight[m]>pic[k][m]+weight[k]&&!visit[m])
		 	{
		 		weight[m]=pic[k][m]+weight[k]; //将单点间距离与新更新值距离比较求最小
			}
		} 
	} 
}

和prim唯一一点不同的是,其他点存的距离为一段距离,未连接之前是最大值,连接过后就是某一段加某一段,weight数组里面存的是起始点到各点之间的距离。

  • 技巧:当你需要多源最短路而苦于Floyd的算法复杂度时,你不妨换种思路,把终点当做起点,而你需要求的其他顶点到终点的距离自然就有了。
算法2:Floyd算法

唯一的缺点就是时间复杂度过高(On^3),在算法实现时需要注意arr[i][k]+arr[k][j]的溢出问题所以可能需要long long数组。

void floyd()//算法模板 
{
	for(int k=0;k<=n;k++)
		for(int i=0;i<=n;i++)
			for(int j=0;j<=n;j++)
				if(arr[i][j]>arr[i][k]+arr[k][j])
					arr[i][j]=arr[i][k]+arr[k][j];
}

n表示点的个数,arr里面存取的是点到点的路径值,经过算法计算后,点到点的距离即为最小,可以求各个点之间的。

算法3:bellman-ford算法

之前遗漏,有待补充

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值