一、演算法描述
在一張有環的圖中,通過 $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...