### Floyd
-最小环是自己到自己的距离,所以我们强迫最短路出去跑一遍就行了。
+记原图中 $u,v$ 之间边的边权为 $val\left(u,v\right)$。
-æ\80\8eä¹\88强迫ï¼\9f
+æ\88\91们注æ\84\8få\88° Floyd ç®\97æ³\95æ\9c\89ä¸\80个æ\80§è´¨ï¼\9aå\9c¨æ\9c\80å¤\96å±\82循ç\8e¯å\88°ç\82¹ $k$ æ\97¶ï¼\88å°\9aæ\9cªå¼\80å§\8b第 $k$ 次循ç\8e¯ï¼\89ï¼\8cæ\9c\80ç\9fè·¯æ\95°ç»\84 $dis$ ä¸ï¼\8c$dis_{u,v}$ 表示ç\9a\84æ\98¯ä»\8e $u$ å\88° $v$ ä¸\94ä»\85ç»\8fè¿\87ç¼\96å\8f·å\9c¨ $\left[1, k\right)$ å\8cºé\97´ä¸ç\9a\84ç\82¹ç\9a\84æ\9c\80ç\9fè·¯ã\80\82
-对于所有的 $i$ ,使它自己到自己的距离为 $\infty$ ,也就是
+由最小环的定义可知其至少有三个顶点,设其中编号最大的顶点为 $w$,环上与 $w$ 相邻两侧的两个点为 $u,v$,则在最外层循环枚举到 $k=w$ 时,该环的长度即为 $dis_{u,v}+val\left(v,w\right)+val\left(w,u\right)$。
-```cpp
-dis[i][i] = (1 << 30);
-```
-
-然后利用 Floyd 的性质,跑完之后对所有的 $dis[i][i]$ 取 $\min$ 即可。
+故在循环时对于每个 $k$ 枚举满足 $i<k,j<k$ 的 $(i,j)$,更新答案即可。
时间复杂度: $O(n^3)$
+下面给出 C++ 的参考实现:
+
+```cpp
+int val[maxn + 1][maxn + 1]; // 原图的邻接矩阵
+inline int floyd(const int &n) {
+ static int dis[maxn + 1][maxn + 1]; // 最短路矩阵
+ for (int i = 1; i <= n; ++i)
+ for (int j = 1; j <= n; ++j)
+ dis[i][j] = val[i][j]; // 初始化最短路矩阵
+ int ans = inf;
+ for (int k = 1; k <= n; ++k) {
+ for (int i = 1; i < k; ++i)
+ for (int j = 1; j < i; ++j)
+ ans = std::min(ans, dis[i][j] + val[i][k] + val[k][j]); // 更新答案
+ for (int i = 1; i <= n; ++i)
+ for (int j = 1; j <= n; ++j)
+ dis[i][j] = std::min(dis[i][j], dis[i][k] + dis[k][j]); // 正常的 floyd 更新最短路矩阵
+ } return ans;
+}
+```
+
## 例题
GDOI2018 Day2 巡逻