timus1004 最小環 Floyd 演算法

2022-09-15 18:42:10 字數 1130 閱讀 9250

通過別人的資料搞了好久才成功,果然還是不夠成熟

做題目還是演算法不能融會貫通      

大意即找出圖中至少3個頂點的環,且將環中點按順序輸出

用floyd演算法求最小環

因為floyd演算法求最短路徑是通過中間量k的增加而更新的

演算法流程:

對於k,我們知道利用floyd演算法求出任意兩點i,j最短距離,僅通過路徑i-()-j,其中()中的節點編號均<=k-1

可以這樣證明:

設最小環上最大點的編號為k0;則當k=k0時,對於任意與k0相接兩點i,j兩者

1.對於環的剩下一部分必然是i到j的最短路徑,因為最佳

2.最短路徑必然是通過,否則該最小環最大編號必然大於k,故ans=f[i][j]+graph[i][k]+graph[j][k]   (f[i][j]表示當前通過前k-1點為中間路徑的i-j的最短路徑)

故通過列舉k,取ans=min(ans,f[i][j]+graph[i][k]+graph[j][k])  其中(i,j而環順序只需通過計算每次更新f[i][j]時的k記錄pre[i][j]=k,之後通過遞迴即可得到,  

需要注意的是:每次更新ans時就要將路徑記錄下來,不然之後可能路徑會更新時被改變,這個改變可不代表路徑還會縮短,首先要明白該演算法必然能夠求出最小環,故若求出最小環後可能之後縮短路徑是會重邊,即比如i到j的距離通過k後變短了,可是是重邊得來的沒有意義

#include#include#includeint f[105][105],pre[105][105],graph[105][105],ans,a[1000];

const int maxn=100000000;

int print(int i,int j)

int main()

memset(pre,0,sizeof(pre));

ans=maxn;

scanf("%d",&m);

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

if(f[k][j]>l)

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

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

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

if(i!=k&&j!=k&&i!=j)

if(f[i][j]>f[i][k]+f[k][j])

}if(ans

ural 1004(floyd 求最小環)

poj暫時出問題。就先做乙個這裡的題了。簡單題。求無向圖的最小環。floyd演算法。include include includeusing namespace std const int inf 100000000 int maze 110 110 dis 110 110 path 110 pi ...

Ural 1004 FLOYD最小環問題

題目大意 給出一些雙向邊,求圖中的乙個最小環,當 被選中時,不能被選,按順序輸出這個最小環,無解則輸出。題目既然要求最小環,資料範圍還這麼小,容易聯想到 並且這裡是雙向邊也沒有什麼關係,因為只能選一條,但題目比較麻煩的地方就是要輸出這個環,我的處理好像和機房的人不一樣。我想到的辦法是對於每乙個 j的...

floyd求最小環

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