Floyd求最小環

2022-10-09 20:51:14 字數 1573 閱讀 6422

一、演算法描述

在一張有環的圖中,通過 $o(n^3)$ 的時間效率求出邊長最小的環

二、原理與正確性推導

前置知識:

$\text$ 正確性推導:

floyd的遞推公式如下

$$\dp[i][j]=\min_(d[i][k]+d[k][j])

$$所以,當 $dp[i][k]$ 和 $dp[k][j]$ 都取最小值時,由公式珂知 $dp[i][j]$ 會取到最小值

證明:設 $i$ 和 $j$ 之間的最短路徑上的節點集中(不包含 $i$ 、 $j$ ),編號最大為 $x$

$$\therefore 當k=x時,d[i][j]一定能得到最小值

$$$$

用強歸納法證明

$$$$

設i到x中間編號最大的是x_1,x到j中間編號最大的是x_2

$$$$

\because x是i到j中間編號最大的

$$$$

\therefore x_1\lt x,x_2\lt x

$$$$

\therefore 根據結論,k=x_1時,d[i][k]已取得最小值

$$$$

k=x_2時d[x][j]已取得最小值

$$$$

\therefore 當k=x時,d[i][k]和d[k][j]都已取得最小值

$$$$

\therefore 當k=x時,d[i][j]能取得最小值

$$$$

\tiny q.e.d

$$既然已經證明了上面的公式是正確的,那麼根據公式寫出的 $floyd$ 演算法也應是正確的

我們首先寫出 $floyd$ 的核心**

for(int k=1;k<=n;k++)//以k為中轉點

for(int i=1;i<=n;i++)//i為起點

for(int j=1;j<=n;j++)//j為終點

d[i][j]=min(d[i][j],d[i][k]+d[k][j]);

對這個演算法進行分析珂知

在 $floyd$ 演算法列舉第 $k$ 個中轉點時,已經得到了前 $k-1$ 個中轉點的最短路徑

這 $k-1$ 個點不包括點 $k$ ,並且他們的最短路徑也不經過點 $k$ (排除起點、終點)

那麼我們從前 $k-1$ 個點中選取兩個點 $i,j$

由上珂知:由 $i$ 到 $j$ 的最短路徑已經求出

如果 $j$ 能到 $k$ ,且 $k$ 能到 $i$

那麼連線 $i-j-k-i$ ,我們就得到了包含 $$ 三個點的最小環

最後列舉所有用這個方法算出的最小環,求最小即珂

三、例題及**

p6175 無向圖的最小環問題

由於題目中的 $1\le n\le 100$ ,我們珂以用時間效率為 $o(n^3)$ 的 $floyd$ 來求最小環

核心**:

for(int k=1;k<=n;k++){

for(int i=1;iac**:雲剪貼簿

四、優缺點

優點**簡單,珂以直接當作模板背下來

缺點$o(n^3)$ ,大部分題都沒戲

同時因為使用鄰接表存圖,所以記憶體也堪憂

floyd求最小環

floyd求最小環 1 定義 通常來說最小環是針對有向圖而言 從乙個點出發,經過一條簡單路徑回到起點成為環.圖的最小環就是所有環中長度最小的.2.怎樣求最小環呢?的解決方法 dijkstra 任意乙個環的權值,我們都可以看成兩個有邊相連的結點i j的直接距離加上i j間不包含邊 邊i j 的最短路徑...

floyd求最小環

其實floyd求最小環就相當於找出乙個一條只包括1到k 1中節點的路徑,然後把這個路徑與k這個節點相連。這樣是正確的原因是,最小環中一定有乙個最大節點k,當最外層節點是k時,我們一定會列舉到k兩端的兩個節點,這樣就統計出了答案。至於為什麼不能直接用最短路徑,而是要用前k 1個節點跑出來的最短路徑,是...

Floyd求最小環

floyd 可以求解圖上的最小環 這裡需要注意的是無向圖和有向圖的求法是不一樣的 有向圖 正常跑一遍 floyd 再遍歷所有的 dp i i 即自身到自身的距離,便是所求的最小環 includeusing namespace std const int maxn 2005 const int inf...