求最小環入門詳解

2021-07-04 21:55:46 字數 1573 閱讀 4821

floyd求最小環

2011-08-14 9:42

1 定義:

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

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

2.怎樣求最小環呢?

1傳統的解決方法(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。

2.floyd求最小環:

拋開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,即所有點都(x1->x2->......xm)->u屬於當前環,所以x1,x2,⋯ ,xm

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 定義 通常來說最小環是針對有向圖而言 從乙個點出發,經過一條簡單路徑回到起點成為環.圖的最小環就是所有環中長度最小的.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...