Floyd-蒟蒻也能看懂的弗洛伊德算法(当然我是蒟蒻)
今天来讲点图论的知识,来看看最短路径的一个求法(所有的求法我以后会写,也有可能咕咕咕)
你们都说图看着没意思不好看,那今天就来点情景
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。 暑假,_GC准备去一些城市旅游。有些城市之间有公路,有些城市之间则没有,如下图。为了节省经费以及方便计划旅程,_GC希望在出发之前知道任意两个城市之前的最短路程。


for (int k = 1; k <= n; ++k) for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) { access[i][j] = min(access[i][j], access[i][k] + access[k][j]); }在只允许经过1号顶点的情况下,任意两点之间的最短路程更新为:


1 //经过1号顶点 2 for(i=1;i<=n;i++) 3 for(j=1;j<=n;j++) 4 if (e[i][j] > e[i][1]+e[1][j]) e[i][j]=e[i][1]+e[1][j]; 5 //经过2号顶点 6 for(i=1;i<=n;i++) 7 for(j=1;j<=n;j++) 8 if (e[i][j] > e[i][2]+e[2][j]) e[i][j]=e[i][2]+e[2][j];




for (int k = 1; k <= n; ++k) for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) { access[i][j] = min(access[i][j], access[i][k] + access[k][j]); }这段代码的基本思想就是:最开始只允许经过1号顶点进行中转,接下来只允许经过1和2号顶点进行中转……允许经过1~n号所有顶点进行中转,求任意两点之间的最短路程。用一句话概括就是:从i号顶点到j号顶点只经过前k号点的最短路程。
另外需要注意的是:Floyd-Warshall算法不能解决带有“负权回路”(或者叫“负权环”)的图,因为带有“负权回路”的图没有最短路。例如下面这个图就不存在1号顶点到3号顶点的最短路径。因为1->2->3->1->2->3->…->1->2->3这样路径中,每绕一次1->-2>3这样的环,最短路就会减少1,永远找不到最短路。其实如果一个图中带有“负权回路”那么这个图则没有最短路。
现在我们来看看一道例题
P1744 采购特价商品
这个题就是先把所有的坐标读进去,之后对于每一个可联通的商店我们算一次他们的距离存到图里,等到所有的数据都处理完一张图就诞生了,然后跑一遍Floyd,万事大吉
AC代码(一次过真的好久好久没出现了~嘤)
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; struct emmmmmmm { int x, y; } pos[110]; int main() { int n, m, a, b, s, t; double access[110][110]; memset(access, 127, sizeof(access)); scanf("%d", &n); for (int i = 1; i <= n; ++i) scanf("%d%d", &pos[i].x, &pos[i].y); scanf("%d", &m); for (int i = 1; i <= m; ++i) { scanf("%d%d", &a, &b); access[a][b] = access[b][a] = (double)(sqrt(pow(pos[a].x - pos[b].x, 2) + pow(pos[a].y - pos[b].y, 2))); } for (int k = 1; k <= n; ++k) for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) { access[i][j] = min(access[i][j], access[i][k] + access[k][j]); } scanf("%d%d", &s, &t); printf("%.2lf", access[s][t]); return 0; }
最后补一句
Floyd的时间复杂度是o (n^3),空间复杂度是o(n^2)(用的是邻接表)。
以及如果题目中数据范围<=5000,一般就是Floyd没跑了
n方过百万哦~(不过你别打算n^3过十万)

更多精彩