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