floyd求最小環

2021-07-13 21:36:37 字數 2189 閱讀 2357

floyd求最小環

1 定義:

通常來說最小環是針對有向圖而言

從乙個點出發,經過一條簡單路徑回到起點成為環.圖的最小環就是所有環中長度最小的.

2.怎樣求最小環呢?

的解決方法(dijkstra):

任意乙個環的權值,我們都可以看成兩個有邊相連的結點i、j的直接距離加上i、j間不包含邊(邊i->j)的最短路徑。求最短路徑我們第乙個想到的就是dijkstra演算法。而dijkstra所求的是乙個點到所有點的最短距離。用dijkstra所求的i、j的最短距離一定是i、j的直接距離(如果i,j連通),所以我們需要先將i、j的邊從圖中刪除(若i,j不連通,則不用刪除),再用dijkstra求新圖中i、j的最短距離即可。所以我們每次在圖中選取一條邊,把它從圖中刪掉.然後對刪掉的那條邊所對應的2點進行dijkstra,也就是m次dijkstra。

拋開dijkstra演算法,進而我們想到用floyd演算法。我們知道,floyd演算法在進行時會不斷更新矩陣dist(k)。設dist[k,i,j]表示從結點i到結點j且滿足所有中間結點,它們均屬於集合的一條最短路徑的權。其中dist[0,i,j ]即為初始狀態i到j的直接距離。對於乙個給定的賦權有向圖, 求出其中權值和最小的乙個環。我們可以將任意乙個環化成如下形式:u->k->v ->(x1-> x2-> ⋯ xm1)-> u(u與k、k與v都是直接相連的),其中v ->(x1-> 2-> ⋯ m)-> u是指v到u不經過k的一種路徑。

在u,k,v確定的情況下,要使環權值最小, 則要求 (x1一》x2->⋯一》xm)->u路徑權值最小.即要求其為v到u不經過k的最短路徑,則這個經過u,k,v的環的最短路徑就是:[v到u不包含k的最短距離]+dist[o,u,k]+dist[o,k,v]。我們用floyd只能求出任意2點間滿足中間結點均屬於集合的最短路徑,可是我們如何求出v到u不包含k的最短距離呢?**

現在我們給k加乙個限制條件:k為當前環中的序號最大的節點(簡稱最大點)。因為k是最大點,所以當前環中沒有任何乙個點≥k,即所有點都小於k因為v->(x1->x2->……xm)->u屬於當前環,所以x1,x2,⋯ ,xm小於k,即x1,x2.⋯。xm≤k一1。這樣,v到u的最短距離就可以表示成dist[k一1 ,u,v]。dist[k一1,v,u]表示的是從v到u且滿足所有中間結點均屬於集合的一條最短路徑的權。接下來,我們就可以求出v到u不包含k的最短距離了。這裡只是要求不包含k,而上述方法用的是dist[k一1,v,u],求出的路徑永遠不會包含k+l,k+2,⋯ 。萬一所求的最小環中包含k+1,k+2,⋯ 怎麼辦呢?的確,如果最小環中包含比k大的節點,在當前u,k,v所求出的環顯然不是那個最小環。然而我們知道,這個最小環中必定有乙個最大點ko,也就是說,雖然當前k沒有求出我們所需要的最小環,但是當我們從k做到ko的時候,這個環上的所有點都小於ko了.也就是說在k=ko時一定能求出這個最小環。我們用乙個例項來說明:假設最小環為1—3—4—5—6—2—1。的確,在u=l,v=4,k=3時,k<6,dist[3,4,1]的確求出的不是4—5—6—2—1這個環,但是,當u=4,v=6,k=5或u=5,v=2,k=6時,dist[k,v,u]表示的都是這條最短路徑.所以我們在floyd以後,只要列舉u.v,k三個變數即可求出最小環。時間複雜度為o(n3)。我們可以發現,floyd和最後列舉u,v,k三個變數求最小環的過程都是u,v,k三個變數,所以我們可以將其合併。這樣,我們在k變數變化的同時,也就是進行floyd演算法的同時,尋找最大點為k的最小環。

3.模板

includeusing

namespace

std;

const

int maxn=105;

const

int inf=10000000;

int dist[maxn][maxn],g[maxn][maxn];

int fa[maxn][maxn],path[maxn];

int n,m,num,minc;

void floyd()

path[num++]=i;

path[num++]=k;}}

for(i=1;i<=n;i++)

for(j=1;j<=n;j++)}}

}int main()

while(m--)

floyd();

if(minc==inf)

printf("no solution.\n");

else

}system("pause");

return

0;}

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...

floyd求最小環

floyd 演算法保證了最外層迴圈到 k 時所有頂點間已求得以 0 k 1 為中間點的最短路徑。乙個環至少有3個頂點,設某環編號最大的頂點為 l 在環中直接與之相連的兩個頂點編號分別為 m 和 n m,n l 則最大編號為 l 的最小環長度即為 graph m,l graph n,l dist m,...