最短距离问题(Floyed-Warshall算法)

该博客介绍了如何使用Floyed-Warshall算法解决平面上n个点之间的最短路径问题。内容包括问题描述、输入输出格式、样例以及算法的应用和实现方法,强调了算法在处理负权边时的局限性。

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

题目链接:

https://begin.lydsy.com/JudgeOnline/problem.php?cid=1318&pid=10

Problem K: 最短路径问题

Time Limit: 1 Sec Memory Limit: 128 MB

Description

平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现在的任务是找出从一点到另一点之间的最短路径。

Input

共n+m+3行,其中:
第一行为整数n。
第2行到第n+1行(共n行),每行两个整数x和y,描述了一个点的坐标。
第n+2行为一个整数m,表示图中连线的个数。
此后的m行,每行描述一条连线,由两个整数i和j组成,表示第i个点和第j个点之间有连线。
最后一行:两个整数s和t,分别表示源点和目标点。

Output

仅一行,一个实数(保留两位小数),表示从s到t的最短路径长度。

Sample Input

5
0 0
2 0
2 2
0 2
3 1
5
1 2
1 3
1 4
2 5
3 5
1 5

Sample Output

3.41

HINT

题目分析:

1.引子

首先本题一看,就知道是最小路径问题,那么我们首先了解一下什么是带权图
我们把边带有权值的图称为带权图。
摆上一张图:
在这里插入图片描述
我们可以看到图中有许多点,且任两点之间会有不同的路径相连。最短路径就是指连接两点的这些路径中最短的一条。

2.解决方法

我们有四种算法可以有效解决这个问题,但有一点要特别注意,边的权值可以为负,当出现负边权时,有些算法就不再适用。
算法1:Floyed-Warshall算法 O(n^3)
算法2:Dijkstra算法 O(n^2)
算法3:Bellman-Ford算法 O(NE) [N为顶点数,E为边数]
算法3:Bellman-Ford算法 O(NE) [N为顶点数,E为边数]
算法4:SPFA算法 O(KE) [同3,但使用队列维护,优化算法]
奈何本蒟蒻只学了Floyed-Warshall算法 O(n^3),所以这里不再赘述。
我们来看看算法的解释:
一、 作用:
1.求多源最短路径;
2.判断图中两点是否相连。
PS:算法较为简单,容易理解,但不适用数据规模很大的情况。
二、 实现方法:
设置f[i][j]为点i到j的最短距离,初始值设为INF,设置三层循环,分为d,i,j,则f[i][j] = min(f[i][j],f[i][d]+f[d][j]);
循环结束,则可求出各点到各点的最短距离。

看不懂没关系,其实一张图就能说明一切:
在这里插入图片描述
我们发现三点间各有联系,那么从1到2有两条路径:
1. 1 to 2:f[1][2]=6
2. 1 to 3 to 2 : f[1][3]+f[3][2]=3

很明显,从1到2的最短路径是2.
那么也就是说用路径2.来替代1.更新1到2的最短距离。
所以我们可以很清楚的发现:
不断地枚举中间点,算出出发点经中间点到结束点的距离来与原来f[i][j]的值进行比较。
那么思路也很清晰了,代码实现如下:

bool check(int x,int y,int z)
{
   
	return (x!=y)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值