floyd最小環 詳細講解
轉載自:http://m.blog.csdn.net/blog/qq909157370/9225109#
注意!這裡寫成 #define data 0x3f3f3f3f memset(map,data,sizeof(map))是wrong 按理來說應該不錯,鬱悶,以後還是迴圈賦值然後巨集定義#define data 100000000Problem Description
杭州有N個景區,景區之間有一些雙向的路來連線,現在8600想找一條旅遊路線,這個路線從A點出發並且最後回到A點,假設經過的路線為V1,V2,....VK,V1,那麼必須滿足K>2,就是說至除了出發點以外至少要經過2個其他不同的景區,而且不能重複經過同一個景區。現在
Input
第一行是2個整數N和M(N <= 100, M <= 1000),代表景區的個數和道路的條數。接下來的M行裡,每行包括3個整數a,b,c.代表a和b之間有一條通路,並且需要花費c元(c <= 100)。
Output
對於每個測試例項,如果能找到這樣一條路線的話,輸出花費的最小值。如果找不到的話,輸出"It's impossible.".
Sample Input
3 3 1 2 1 2 3 1 1 3 1 3 3 1 2 1 1 2 3 2 3 1
Sample Output
3 It's impossible.
對於找最小環,而且要經過至少兩個節點,權值和最小,演算法是floyd,但該注意和理解的地方實在很多 1.定義和理解:轉自 在圖論中經常會遇到這樣的問題,在一個有向圖裡,求出任意兩個節點之間的最短距離。我們在離散數學、資料結構課上都遇到過這個問題,在計算機網路裡介紹網路層的時候好像也遇到過這個問題,記不請了... 但是書本上一律採取的是Dijkstra演算法,通過Dijkstra演算法可以求出單源最短路徑,然後逐個節點利用Dijkstra演算法就可以了。不過在這裡想換換口味,採取Robert Floyd提出的演算法來解決這個問題。下面讓我們先把問題稍微的形式化一下:
for(int i=0; i<n; i++) for(int j=0; j<n; j++) for(int k=0; k<n; k++)
問題出在我們太早的把i-k-j的距離確定下來了,假設一旦找到了i-p-j最短的距離後,i到j就相當處理完了,以後不會在改變了,一旦以後有使i到j的更短的距離時也不能再去更新了,所以結果一定是不對的。所以應當象下面一樣來寫程式:
for(int k=0; k<n; k++) for(int i=0; i<n; i++) for(int j=0; j<n; j++)
這樣作的意義在於固定了k,把所有i到j而經過k的距離找出來,然後象開頭所提到的那樣進行比較和重寫,因為k是在最外層的,所以會把所有的i到j都處理完後,才會移動到下一個k,這樣就不會有問題了,看來多層迴圈的時候,我們一定要當心,否則很容易就弄錯了。 接下來就要看一看如何找出最短路徑所行經的城市了,這裡要用到另一個矩陣P,它的定義是這樣的:p(ij)的值如果為p,就表示i到j的最短行經為i->...->p->j,也就是說p是i到j的最短行徑中的j之前的最後一個城市。P矩陣的初值為p(ij)=i。有了這個矩陣之後,要找最短路徑就輕而易舉了。對於i到j而言找出p(ij),令為p,就知道了路徑i->...->p->j;再去找p(ip),如果值為q,i到p的最短路徑為i->...->q->p;再去找p(iq),如果值為r,i到q的最短路徑為i->...->r->q;所以一再反覆,到了某個p(it)的值為i時,就表示i到t的最短路徑為i->t,就會的到答案了,i到j的最短行徑為i->t->...->q->p->j。因為上述的演算法是從終點到起點的順序找出來的,所以輸出的時候要把它倒過來。 但是,如何動態的回填P矩陣的值呢?回想一下,當d(ij)>d(ik)+d(kj)時,就要讓i到j的最短路徑改為走i->...->k->...->j這一條路,但是d(kj)的值是已知的,換句話說,就是k->...->j這條路是已知的,所以k->...->j這條路上j的上一個城市(即p(kj))也是已知的,當然,因為要改走i->...->k->...->j這一條路,j的上一個城市正好是p(kj)。所以一旦發現d(ij)>d(ik)+d(kj),就把p(kj)存入p(ij)。
2 對於程式碼的理解:
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 usingnamespace std;
5 #define data 100000000
6 #define N 110
7 #define min(x,y) ((x)>(y)?(y):(x))
8 int map[N][N],dis[N][N];
9 int n,m;
10 void floyd()
11 {
12 int i,j,k,mina=data;
13 for(k=1;k<=n;k++)
14 {
15 //因為路徑i到j的情況只有經過k和不經過k,而要求從一個點至少經過兩個節點返回原點,k每次更新都會使dis[i][j]得到更新,而只有在更新了一次k之後才可以找min,min即是在dis[i][i]最短的情況下的求至少經過兩個點又回到該點的最小距離,所以i和j的值都應該小於k,i的值從1到k-1,而j的值卻跟i的值相關,即i!=j,因為當i=j時,dis[i][j]不是無窮大,而是從i->j->i的值,這就會出現自環,這裡我定義自環為經過一個節點就返回原節點的節點,比如像1->2->1這樣min的值會不準確,這不是經過了兩個節點,所以下面第一個兩層迴圈可以有三種寫法,具體看程式碼
16
17 //當要擴充第k個節點時,前k-1個節點已經用過,並且是用於更新最短路徑dis[i][j]這就是第二個兩層for迴圈,所以在更新k之前已經有一條最短路徑從i到達j,此時再來尋找另外一個從i到j的路徑,map[j][k]+map[k][i],如果有的話則一定形成了從i回到i的環,比如 1->2值為1,2->3值為2,3->4值為3,4->1值為4,則第一次存在從1到3的最短路,再尋找時找到了1到4,4到3的路徑,則形成了環,而且是最小的,注意第一個迴圈中加上的值是map[j][k]和map[k][i]的值,map的是值都是初始值,不會變化,而dis在不斷更新
18 for(i=1;i<k;i++)
19 {
20 for(j=i+1;j<k;j++)
21 {
22 mina=min(dis[i][j]+map[j][k]+map[k][i],mina);
23 }
24 }
25 for(i=1;i<=n;i++)
26 {
27 for(j=1;j<=n;j++)
28 {
29 if(dis[i][j]>(dis[i][k]+dis[k][j]))
30 dis[i][j]=dis[i][k]+dis[k][j];
31 }
32 }
33 }
34 if(mina<data)
35 printf("%d\n",mina);
36 else
37 printf("It's impossible.\n");
38 }
39 int main()
40 {
41 int a,b,c,i,j;
42 while(scanf("%d%d",&n,&m)!=EOF)
43 {
44 for(i=0;i<=n;i++)
45 for(j=0;j<=n;j++)
46 {
47 map[i][j]=data;
48 dis[i][j]=data;
49 }
50 for(i=0;i<m;i++)
51 {
52 scanf("%d%d%d",&a,&b,&c);
53 if(map[a][b]>c)
54 {
55 map[a][b]=map[b][a]=c;
56 dis[a][b]=dis[b][a]=c;
57 }
58 }
59 floyd();
60 }
轉載自:http://m.blog.csdn.net/blog/qq909157370/9225109#
注意!這裡寫成 #define data 0x3f3f3f3f memset(map,data,sizeof(map))是wrong 按理來說應該不錯,鬱悶,以後還是迴圈賦值然 sig span 利用 pac href sin 有用 tar cpp POJ - 1734
思路 : Floyd 實質 dp ,優化掉了第三維. dp [ i ] [ j ] [ k ] 指的是前k個點優化後 i -> j 的最短路。
所以我們就可
其實我已經會了。。但今天寫錯了一次。。。。實在恐怖。。所以我決定還是深度解析這個floyd演算法
Floyd-warshall
1.擺出問題
先擺出最簡單問題,給你圖,詢問a,b求a,b間最短路
不會floyd的時候,,我是紮紮實實的對每個點求單源最短路。。。
後來學了fl pri div -a pac for main 之間 ret != pro:二維平面上,給定N個村莊。M個士兵駐守,把村莊圍住,現在我們想留下更多的士兵休息,使得剩下的士兵任然滿足圍住村莊。N,M<500;
sol:即是要找一個最小的環,環把村莊圍住。 由於是環, lin 自己 路徑 三個點 pos 紅色 ++i ont mem 最近學習了floyd的奇妙用處,求解最小環,自己的領悟寫在了紙上。
對於一個最小環,顯然至少要包含三個點(此處不把兩個點的回路稱之為環)
從大體上考慮的話,一定有一個點與左右兩側的點是直接連接的(即不經其他點 int inf cst 而是 不知道 為什麽 class include con hdu1599 floyd求最小環
其實floyd求最小環就相當於找出一個一條只包括1到k-1中節點的路徑,然後把這個路徑與k這個節點相連。這樣是正確的原因是,最小環中一定有一個最大節點k,當 lse urn view ide 不存在 eps 圖片 none 枚舉 模板:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 110;
const int IN
跟hdu1599差不多.。
只是需要輸出方案。
這個可以遞迴求解。
程式碼:
#include<iostream>
#include<cstdio>
#include
每次列舉k時,列舉所有編號小於k的結點i,j(i≠j≠k),可以得出一個經過i,j,k的可行環:a[i][k]+a[k][j]+dist[i][j],即i到j的最短路加上i到k、j到k的直接距離(若兩點之間沒有邊則為∞)。可以證明,若i到j的最短路經過k,則這
最小環改進演算法的證明
設一個環中的最大結點為k(編號最大), 與他相連的兩個點為i, j, 這個環的最短長度為g[i][k]+g[k][j]+i到j的路徑中所有結點編號都小於k的最短路徑長度。
根據
https://vijos.org/p/1423
題目描述
年久失修的賽道令國際汽聯十分不滿。汽聯命令主辦方立即對賽道進行調整,否則將取消其主辦權。主辦方當然必須馬上開始行動。
賽道測評人員經過了三天三夜的資料採集,選出了若干可以使用的道路和各道路行駛所需的時間。這些道路包括若干直道
觀光旅遊Time Limit:1000MS Memory Limit:65536K Total Submit:1 Accepted:0Description背景 Background 湖南師大附中
Floyd演算法:用來找出每對點之間的最短距離。圖可以是無向圖,也可以是有向圖,邊權可為正,也可以為負,唯一要求是不能有負環。
1.初始化:將Map[][]中的資料複製到Dist[][]中作為每對頂點
給定一個無向圖,求出圖中由 3個及以上個點構成的環的邊權和 中的最小值。(一個點不能遍歷多次)在floyd時,先迴圈k,然後是i和j,你會發現在每次進入一個新的k迴圈時,每一個d(i,j)都儲存著從i到j,只經歷了編號不超過k-1的節點的最短路、於是,min{d(i,j)+
find the mincost route
Time Limit: 1000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3758
題意:旅遊公司要開發一條新的路線 , 要求這是一個總路程儘可能短的環 , 並且不能只含兩個城市 , 除開起點外 ,
不能重複走之前走過的城市 , 輸出這條路線?
Floyd演算法求最小環
程式碼:
//用floyd演算法 , 求有向圖的最小環
#include
#include
#include
#i
【連結】
【題意】
找最小環
【思路】
ffloyd跑一邊,記錄轉移路徑
【程式碼】
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1004;
const int view logs scan 最優 根據 ted 算法 以及 too 背景
湖南師大附中成為百年名校之後,每年要接待大批的遊客前來參觀。學校認為大力發展旅遊業,可以帶來一筆可觀的收入。
描述
學校裏面有N個景點。兩個景點之間可能直接有道路相連,用Dist[I,J]表示它的長 inf 計算 最小 star while arch mes targe space 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4370
題目大意:有一個n*n的矩陣Cij(1<=i,j<=n),要找到矩陣Xi std oss 距離 IT ace math 技術 scan closed 任意一個環的權值,我們都可以看成兩個有邊相連的結點i、j的直接距離加上i、j間不包含邊(邊i->j)的最短路徑。
求最短路徑我們第一個想到的就是Dijkstra算法。
而Dijkstra所求的 相關推薦
floyd最小環 詳細講解
Sightseeing trip POJ - 1734 -Floyd 最小環
多源最短路·floyd && 最小環演算法
HDU - 6080 :度度熊保護村莊 (凸包,floyd最小環)(VJ1900題達成)
關於Floyd求解最小環的問題
floyd求最小環
弗洛伊德Floyd求最小環
2018.09.15 poj1734Sightseeing trip(floyd求最小環)
floyd 判最小環
floyd改進版求最小環
Vijos - 最佳路線(Floyd+有向圖最小環)
Floyd演算法求圖最小環
多源最短路徑Floyd、Floyd求最小環【模板】
floyd求無向圖最小環——poj1734
hdu 1599 find the mincost route【floyd求最小環】
poj 1734 Floyd算求有向圖的最小環
101572I Import Spaghetti 】【floyd求最小環】【記錄路徑】
vijos 觀光旅遊 最小環fl 呆詳看
HDU 4370 0 or 1(spfa+思維建圖+計算最小環)
dijkstra求最小環