所谓最短路径,就是求一个图(无向或有向都行)每个点到每个点的最短路
所谓Floyd,其实原理很简单,假设 i 点到 j 点的最短路用 f[i][j] 代替,那么若 i 点到 j 点有路就存进 f[i][j] 里,没有路就令 f[i][j]=2147483647 注意 f 数组需要开 longlong
那么要求 f[i][j] 的最短路,我们需要枚举一个点k, 这里需要保证 i!=j , i!=k , j!=k 。若我们从i点绕k,再从k点到j点需要走的长度比直接从i点到j点的路径要长,那么就更新 f[i][j] 的最短路: f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
整个Floyd的速度在 O(n^3)
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)//k一定要写在最前面
if(i!=j&&i!=k&&j!=k)//不相同
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);//比对最短路
所谓dijkstra,其实原理很简单,我们假设 i 点直接 j 点用 f[i][j] 代替(与Floyd相同),那么若 i 点到 j 点有路就存进 f[i][j] 里,没有路就令 f[i][j]=2147483647 注意 f 数组需要开 longlong
dijkstra求的是给出一个点,求这个点到其他点的最短路,这个最短路我们用 dis 数组表示(不是 diss 的意思)。我们还需要一个 visit 数组,它究竟指什么意思呢,待会再讲。
接下来我们需要在这 n 个点里找目前离它最近的点,并且保证这个点我们没有它与其他点进行求最短路的操作,例如我们找到了 j 点,它是目前离 i 最近,且没有它与其他点进行求最短路的操作,那么最小值 mi 值等于 dis[j] ,利用一个指针 p 指向当前的j点。而没有它与其他点进行求最短路的操作的判断就用 visit 数组记录 false 或 true
然后我们要进行求最短路的操作,枚举所有的点,只要 dis[p]+f[p][j]<dis[j] 及起点到p点的最小值加上 f 数组里记录的 p 点到 j 点的路径长度,若比起点到j点的最小值更好(小),就更新 dis[j]