第一行国际惯例——咕咕咕。
1.floyd算法原理是动态规划
2.时间复杂度是O(n^3)(n是点的个数
3.适用于点比较少的情况
4.适用于多源最短路(跑完floyd后直接输出数组即可得到从x到y的最短路
5.算法核心是利用两点之间的其他点来中转,从而更新最短路。
本代码以洛谷2910为例
与普通模板不同的是,2910多了一个规定路径,只需累加即可。
#include <iostream>
#include <cstdio>
#include <algorithm>
#define maxn 1005
#define inf 0x3f3f3f3f
using namespace std;
int p[maxn][maxn];//用于存储每两个点之间的距离
int n,m;
void init()
{
for(int i=0; i<maxn; ++i)
for(int j=0; j<maxn; ++j)
{
p[i][j]=inf;
}
}//初始化为inf
void floyd()
{
for(int k=1; k<=n; ++k)
for(int i=1; i<=n; ++i)
for(int j=1; j<=n; ++j)
{
if(p[i][k]+p[k][j]<p[i][j])
p[i][j]=p[i][k]+p[k][j];
}//求ij之间的最短路
}//n个点
int main()
{
init();
int a[100005];
scanf("%d%d",&n,&m);//有n个点m条边
for(int i=0; i<m; ++i)
{
scanf("%d",&a[i]);
}
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=n; ++j)
{
int x;
scanf("%d",&x);
if(i==j)
continue;
p[i][j]=x;
}
}//用p来存每两个点直接距离
floyd();
int sum=0;
for(int i=1; i<m; ++i)
{
sum+=p[a[i-1]][a[i]];
}
cout<<sum<<'\n';
return 0;
}
附一个练习题SDNU1224
注意输入双向路径。感谢syh同学一语道破?
再附一个练习题洛谷P1119
这题思路是按时间每次更新x到y的最短路,若无法更新,即res为inf时返回-1。同时因为保证了t是不下降的,所以之前使用过的中转点就不再更新了(用一个访问标记即可),不然会超时。
再附一个洛谷P3905
其实最短路用啥写不行啊,毕竟数据范围合适不超时就行呗(所以我奔着spfa去的用了floyd)。这题很巧妙的是,求需要重建的路的长度,所以可以用有路没破坏的是0,有路被破坏的是权值,没路是inf,求最短路即可。