圖的四種最短路徑算法

本文總結了圖的幾種最短路徑算法的實現:深度或廣度優先搜索算法,弗洛伊德算法,迪杰斯特拉算法,Bellman-Ford算法

?

1),深度或廣度優先搜索算法(解決單源最短路徑)
從起始結點開始訪問所有的深度遍歷路徑或廣度優先路徑,則到達終點結點的路徑有多條,取其中路徑權值最短的一條則為最短路徑。

下面是核心代碼:

?

[cpp]?view plain?copy

  1. void?dfs(int?cur,?int?dst){????
  2. ????/***operation***/????
  3. ????
  4. ????/***operation***/????
  5. ????if(minPath?<?dst)?return;//當前走過路徑大于之前最短路徑,沒必要再走下去????
  6. ????if(cur?==?n){//臨界條件????
  7. ????????if(minPath?>?dst)?minPath?=?dst;????
  8. ????????return;????
  9. ????}????
  10. ????else{????
  11. ????????int?i;????
  12. ????????for(i?=?1;?i?<=?n;?i++){????
  13. ????????????if(edge[cur][i]?!=?inf?&&?edge[cur][i]?!=?0?&&?mark[i]?==?0){????
  14. ????????????????mark[i]?=?1;????
  15. ????????????????dfs(i,?dst+edge[cur][i]);????
  16. ????????????????mark[i]?=?0;??//需要在深度遍歷返回時將訪問標志置0??????????????
  17. ????????????}????
  18. ????????}????
  19. ????????return;????
  20. ????}????
  21. }????

例1:下面是城市的地圖,注意是單向圖,求城市1到城市5的最短距離。(引用的是上次總結的圖論(一)中1)的例2)

?

[cpp]?view plain?copy

  1. /***先輸入n個結點,m條邊,之后輸入有向圖的m條邊,邊的前兩元素表示起始結點,第三個值表權值,輸出1號城市到n號城市的最短距離***/????
  2. /***算法的思路是訪問所有的深度遍歷路徑,需要在深度遍歷返回時將訪問標志置0***/????
  3. #include?<iostream>????
  4. #include?<iomanip>????
  5. #define?nmax?110????
  6. #define?inf?999999999????
  7. using?namespace?std;????
  8. int?n,?m,?minPath,?edge[nmax][nmax],?mark[nmax];//結點數,邊數,最小路徑,鄰接矩陣,結點訪問標記????
  9. void?dfs(int?cur,?int?dst){????
  10. ????/***operation***/????
  11. ????
  12. ????/***operation***/????
  13. ????if(minPath?<?dst)?return;//當前走過路徑大于之前最短路徑,沒必要再走下去????
  14. ????if(cur?==?n){//臨界條件????
  15. ????????if(minPath?>?dst)?minPath?=?dst;????
  16. ????????return;????
  17. ????}????
  18. ????else{????
  19. ????????int?i;????
  20. ????????for(i?=?1;?i?<=?n;?i++){????
  21. ????????????if(edge[cur][i]?!=?inf?&&?edge[cur][i]?!=?0?&&?mark[i]?==?0){????
  22. ????????????????mark[i]?=?1;????
  23. ????????????????dfs(i,?dst+edge[cur][i]);????
  24. ????????????????mark[i]?=?0;????????????????
  25. ????????????}????
  26. ????????}????
  27. ????????return;????
  28. ????}????
  29. }????
  30. ????
  31. int?main(){????
  32. ????while(cin?>>?n?>>?m?&&?n?!=?0){????
  33. ????????//初始化鄰接矩陣????
  34. ????????int?i,?j;????
  35. ????????for(i?=?1;?i?<=?n;?i++){????
  36. ????????????for(j?=?1;?j?<=?n;?j++){????
  37. ????????????????edge[i][j]?=?inf;????
  38. ????????????}????
  39. ????????????edge[i][i]?=?0;????
  40. ????????}????
  41. ????????int?a,?b;????
  42. ????????while(m--){????
  43. ????????????cin?>>?a?>>?b;????
  44. ????????????cin?>>?edge[a][b];????
  45. ????????}????
  46. ????????//以dnf(1)為起點開始遞歸遍歷????
  47. ????????memset(mark,?0,?sizeof(mark));????
  48. ????????minPath?=?inf;????
  49. ????????mark[1]?=?1;????
  50. ????????dfs(1,?0);????
  51. ????????cout?<<?minPath?<<?endl;????
  52. ????}????
  53. ????return?0;????
  54. }????

程序運行結果如下:

?

?

2),弗洛伊德算法(解決多源最短路徑):時間復雜度O(n^3),空間復雜度O(n^2)
基本思想:最開始只允許經過1號頂點進行中轉,接下來只允許經過1號和2號頂點進行中轉......允許經過1~n號所有頂點進行中轉,來不斷動態更新任意兩點之間的最短路程。即求從i號頂點到j號頂點只經過前k號點的最短路程。

分析如下:1,首先構建鄰接矩陣Floyd[n+1][n+1],假如現在只允許經過1號結點,求任意兩點間的最短路程,很顯然Floyd[i][j] = min{Floyd[i][j], Floyd[i][1]+Floyd[1][j]},代碼如下:

?

[cpp]?view plain?copy

  1. for(i?=?1;?i?<=?n;?i++){??
  2. ????for(j?=?1;?j?<=?n;?j++){??
  3. ????????if(Floyd[i][j]?>?Floyd[i][1]?+?Floyd[1][j])??
  4. ????????????Floyd[i][j]?=?Floyd[i][1]?+?Floyd[1][j];??
  5. ????}??
  6. }??

2,接下來繼續求在只允許經過1和2號兩個頂點的情況下任意兩點之間的最短距離,在已經實現了從i號頂點到j號頂點只經過前1號點的最短路程的前提下,現在再插入第2號結點,來看看能不能更新更短路徑,故只需在步驟1求得的Floyd[n+1][n+1]基礎上,進行Floyd[i][j] = min{Floyd[i][j], Floyd[i][2]+Floyd[2][j]};......
3,很顯然,需要n次這樣的更新,表示依次插入了1號,2號......n號結點,最后求得的Floyd[n+1][n+1]是從i號頂點到j號頂點只經過前n號點的最短路程。故核心代碼如下:

?

[cpp]?view plain?copy

  1. #define?inf?99999999??
  2. for(k?=?1;?k?<=?n;?k++){??
  3. ????for(i?=?1;?i?<=?n;?i++){??
  4. ????????for(j?=?1;?j?<=?n;?j++){??
  5. ????????????if(Floyd[i][k]?<?inf?&&?Floyd[k][j]?<?inf?&&?Floyd[i][j]?>?Floyd[i][k]?+?Floyd[k][j])??
  6. ????????????????Floyd[i][j]?=?Floyd[i][k]?+?Floyd[k][j];??
  7. ????????}??
  8. ????}??
  9. }??

例1:尋找最短的從商店到賽場的路線。其中商店在1號結點處,賽場在n號結點處,1~n結點中有m條線路雙向連接。

?

[cpp]?view plain?copy

  1. /***先輸入n,m,再輸入m個三元組,n為路口數,m表示有幾條路其中1為商店,n為賽場,三元組分別表起點,終點,該路徑長,輸出1到n的最短路徑***/??
  2. #include?<iostream>??
  3. using?namespace?std;??
  4. #define?inf?99999999??
  5. #define?nmax?110??
  6. int?edge[nmax][nmax],?n,?m;??
  7. int?main(){??
  8. ????while(cin?>>?n?>>?m?&&?n!=?0){??
  9. ????????//構建鄰接矩陣??
  10. ????????int?i,?j;??
  11. ????????for(i?=?1;?i?<=?n;?i++){??
  12. ????????????for(j?=?1;?j?<=?n;?j++){??
  13. ????????????????edge[i][j]?=?inf;??
  14. ????????????}??
  15. ????????????edge[i][i]?=?0;??
  16. ????????}??
  17. ????????while(m--){??
  18. ????????????cin?>>?i?>>?j;??
  19. ????????????cin?>>?edge[i][j];??
  20. ????????????edge[j][i]?=?edge[i][j];??
  21. ????????}??
  22. ????????//使用弗洛伊德算法??
  23. ????????int?k;??
  24. ????????for(k?=?1;?k?<=?n;?k++){??
  25. ????????????for(i?=?1;?i?<=?n;?i++){??
  26. ????????????????for(j?=?1;?j?<=?n;?j++){??
  27. ????????????????????if(edge[i][k]?<?inf?&&?edge[k][j]?<?inf?&&?edge[i][j]?>?edge[i][k]?+?edge[k][j])??
  28. ????????????????????????edge[i][j]?=?edge[i][k]?+?edge[k][j];??
  29. ????????????????}??
  30. ????????????}??
  31. ????????}??
  32. ????????cout?<<?edge[1][n]?<<?endl;??
  33. ????}??
  34. ????return?0;??
  35. }??

程序運行結果如下:

?

?

3),迪杰斯特拉算法(解決單源最短路徑)
基本思想:每次找到離源點(如1號結點)最近的一個頂點,然后以該頂點為中心進行擴展,最終得到源點到其余所有點的最短路徑。
基本步驟:1,設置標記數組book[]:將所有的頂點分為兩部分,已知最短路徑的頂點集合P和未知最短路徑的頂點集合Q,很顯然最開始集合P只有源點一個頂點。book[i]為1表示在集合P中;
2,設置最短路徑數組dst[]并不斷更新:初始狀態下,令dst[i] = edge[s][i](s為源點,edge為鄰接矩陣),很顯然此時dst[s]=0,book[s]=1。此時,在集合Q中可選擇一個離源點s最近的頂點u加入到P中。并依據以u為新的中心點,對每一條邊進行松弛操作(松弛是指由結點s-->j的途中可以經過點u,并令dst[j]=min{dst[j], dst[u]+edge[u][j]}),并令book[u]=1;
3,在集合Q中再次選擇一個離源點s最近的頂點v加入到P中。并依據v為新的中心點,對每一條邊進行松弛操作(即dst[j]=min{dst[j], dst[v]+edge[v][j]}),并令book[v]=1;
4,重復3,直至集合Q為空。
以下是圖示:

核心代碼如下所示:

?

[cpp]?view plain?copy

  1. #define?inf?99999999??
  2. /***構建鄰接矩陣edge[][],且1為源點***/??
  3. for(i?=?1;?i?<=?n;?i++)?dst[i]?=?edge[1][s];??
  4. for(i?=?1;?i?<=?n;?i++)?book[i]?=?0;??
  5. book[1]?=?1;??
  6. for(i?=?1;?i?<=?n-1;?i++){??
  7. ????//找到離源點最近的頂點u,稱它為新中心點??
  8. ????min?=?inf;??
  9. ????for(j?=?1;?j?<=?n;?j++){??
  10. ????????if(book[j]?==?0?&&?dst[j]?<?min){??
  11. ????????????min?=?dst[j];??
  12. ????????????u?=?j;??
  13. ????????}??
  14. ????}??
  15. ????book[u]?=?1;??
  16. ????//更新最短路徑數組??
  17. ????for(k?=?1;?k?<=?n;?k++){??
  18. ????????if(edge[u][k]?<?inf?&&?book[k]?==?0){??
  19. ????????????if(dst[k]?>?dst[u]?+?edge[u][k])??
  20. ????????????????dst[k]?=?dst[u]?+?edge[u][k];?????????????
  21. ????????}??
  22. ????}??
  23. }??

例1:給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s,終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。
輸入:輸入n,m,點的編號是1~n,然后是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最后一行是兩個數s,t;起點s,終點 t。n和m為 0 時輸入結束。(1<n<=1000, 0<m<100000, s != t)
輸出:輸出一行,有兩個數, 最短距離及其花費。
分析:由于每條邊有長度d和花費p,最好構建邊結構體存放,此外可以使用鄰接鏈表,使用鄰接鏈表時需要將上面的核心代碼修改幾個地方:

1,初始化dst[]時使用結點1的鄰接鏈表;
2,更新最短路徑數組時,k的范圍由1~n變為1~edge[u].size()。先采用鄰接矩陣解決此題,再使用鄰接表解決此題,兩種方法的思路都一樣:初始化鄰接矩陣或鄰接鏈表,并
初始化最短路徑數組dst ----> n-1輪邊的松弛中,先找到離新源點最近的中心點u,之后根據中心點u為轉折點來更新路徑數組。

使用鄰接矩陣求解:

?

[cpp]?view plain?copy

  1. /***對于無向圖,輸入n,m,點的編號是1~n,然后是m行,每行4個數?a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最后一行是兩個數s,t;起點s,終點?t。***/??
  2. /***n和m為?0?時輸入結束。(1<n<=1000,?0<m<100000,?s?!=?t)?????輸出:輸出一行,有兩個數,?最短距離及其花費。***/??
  3. #include?<iostream>??
  4. #include?<iomanip>??
  5. using?namespace?std;??
  6. #define?nmax?1001??
  7. #define?inf?99999999??
  8. struct?Edge{??
  9. ????int?len;??
  10. ????int?cost;??
  11. };??
  12. Edge?edge[nmax][nmax];??
  13. int?dst[nmax],?spend[nmax],?book[nmax],?n,?m,?stNode,?enNode;??
  14. int?main(){??
  15. ????while(cin?>>?n?>>?m?&&?n?!=?0?&&?m?!=?0){??
  16. ????????int?a,?b,?i,?j;??
  17. ????????//構建鄰接矩陣和最短路徑數組??
  18. ????????for(i?=?1;?i?<=?n;?i++){??
  19. ????????????for(j?=?1;?j?<=?n;?j++){??
  20. ????????????????edge[i][j].cost?=?0;??
  21. ????????????????edge[i][j].len?=?inf;??
  22. ????????????}??
  23. ????????????edge[i][i].len?=?0;??
  24. ????????}??
  25. ????????while(m--){??
  26. ????????????cin?>>?a?>>?b;??
  27. ????????????cin?>>?edge[a][b].len?>>?edge[a][b].cost;??
  28. ????????????edge[b][a].len?=?edge[a][b].len;??
  29. ????????????edge[b][a].cost?=?edge[a][b].cost;??
  30. ????????}??
  31. ????????cin?>>?stNode?>>?enNode;??
  32. ????????for(i?=?1;?i?<=?n;?i++){??
  33. ????????????dst[i]?=?edge[stNode][i].len;??
  34. ????????????spend[i]?=?edge[stNode][i].cost;??
  35. ????????}??
  36. ????????memset(book,?0,?sizeof(book));??
  37. ????????book[stNode]?=?1;??
  38. ????????//開始迪杰斯特拉算法,進行剩余n-1次松弛??
  39. ????????int?k;??
  40. ????????for(k?=?1;?k?<=?n-1;?k++){??
  41. ????????????//找離源點最近的頂點u??
  42. ????????????int?minNode,?min?=?inf;??
  43. ????????????for(i?=?1;?i?<=?n;?i++){??
  44. ????????????????if(book[i]?==?0?&&?min?>?dst[i]?/*?||?min?==?dst[i]&&?edge[stNode][min].cost?>?edge[stNode][i].cost*/){??
  45. ????????????????????min?=?dst[i];??
  46. ????????????????????minNode?=?i;??
  47. ????????????????}??
  48. ????????????}??
  49. ????????????//cout?<<?setw(2)?<<?minNode;??
  50. ????????????book[minNode]?=?1;//易錯點1,錯寫成book[i]=1??
  51. ????????????//以中心點u為轉折點來更新路徑數組和花費數組??
  52. ????????????for(i?=?1;?i?<=?n;?i++){??
  53. ????????????????if(book[i]?==?0?&&?dst[i]?>?dst[minNode]?+?edge[minNode][i].len?||?dst[i]?==?dst[minNode]?+?edge[minNode][i].len?&&?spend[i]?>?spend[minNode]?+?edge[minNode][i].cost){??
  54. ????????????????????dst[i]?=?dst[minNode]?+?edge[minNode][i].len;//易錯點2,錯寫成dst[i]+??
  55. ????????????????????spend[i]?=?spend[minNode]?+?edge[minNode][i].cost;??
  56. ????????????????}??
  57. ????????????}??
  58. ????????}??
  59. ????????cout?<<?dst[enNode]?<<?setw(3)?<<?spend[enNode]?<<?endl;??
  60. ????}??
  61. ????return?0;??
  62. }??

程序運行結果如下:



使用鄰接鏈表求解:

?

[cpp]?view plain?copy

  1. /***對于無向圖,輸入n,m,點的編號是1~n,然后是m行,每行4個數?a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最后一行是兩個數s,t;起點s,終點?t。***/??
  2. /***n和m為?0?時輸入結束。(1<n<=1000,?0<m<100000,?s?!=?t)?????輸出:輸出一行,有兩個數,?最短距離及其花費。***/??
  3. #include?<iostream>??
  4. #include?<iomanip>??
  5. #include?<vector>??
  6. using?namespace?std;??
  7. #define?nmax?1001??
  8. #define?inf?99999999??
  9. struct?Edge{??
  10. ????int?len;??
  11. ????int?cost;??
  12. ????int?next;??
  13. };??
  14. vector<Edge>?edge[nmax];??
  15. int?dst[nmax],?spend[nmax],?book[nmax],?n,?m,?stNode,?enNode;??
  16. int?main(){??
  17. ????while(cin?>>?n?>>?m?&&?n?!=?0?&&?m?!=?0){??
  18. ????????int?a,?b,?i,?j;??
  19. ????????//構建鄰接表和最短路徑數組??
  20. ????????for(i?=?1;?i?<=?n;?i++)?edge[i].clear();??
  21. ????????while(m--){??
  22. ????????????Edge?tmp;??
  23. ????????????cin?>>?a?>>?b;??
  24. ????????????tmp.next?=?b;??
  25. ????????????cin?>>?tmp.len?>>?tmp.cost;??
  26. ????????????edge[a].push_back(tmp);??
  27. ????????????tmp.next?=?a;??
  28. ????????????edge[b].push_back(tmp);??
  29. ????????}??
  30. ????????cin?>>?stNode?>>?enNode;??
  31. ????????for(i?=?1;?i?<=?n;?i++)?dst[i]?=?inf;?//注意2,別忘記寫此句來初始化dst[]??
  32. ????????for(i?=?0;?i?<?edge[stNode].size();?i++){//注意1,從下標0開始存元素,誤寫成i?<=?edge[stNode].size()??
  33. ????????????dst[edge[stNode][i].next]?=?edge[stNode][i].len;??
  34. ????????????//cout?<<?dst[2]?<<?endl;??
  35. ????????????spend[edge[stNode][i].next]?=?edge[stNode][i].cost;??
  36. ????????}??
  37. ????????memset(book,?0,?sizeof(book));??
  38. ????????book[stNode]?=?1;??
  39. ????????//開始迪杰斯特拉算法,進行剩余n-1次松弛??
  40. ????????int?k;??
  41. ????????for(k?=?1;?k?<=?n-1;?k++){??
  42. ????????????//找離源點最近的頂點u??
  43. ????????????int?minnode,?min?=?inf;??
  44. ????????????for(i?=?1;?i?<=?n;?i++){??
  45. ????????????????if(book[i]?==?0?&&?min?>?dst[i]?/*?||?min?==?dst[i]&&?edge[stnode][min].cost?>?edge[stnode][i].cost*/){??
  46. ????????????????????min?=?dst[i];??
  47. ????????????????????minnode?=?i;??
  48. ????????????????}??
  49. ????????????}??
  50. ????????????//cout?<<?setw(2)?<<?minnode;??
  51. ????????????book[minnode]?=?1;//易錯點1,錯寫成book[i]=1??
  52. ????????????//以中心點u為轉折點來更新路徑數組和花費數組??
  53. ????????????for(i?=?0;?i?<?edge[minnode].size();?i++){??
  54. ????????????????int?t?=?edge[minnode][i].next;//別忘了加此句,表示與結點minnode相鄰的點??
  55. ????????????????if(book[t]?==?0?&&?dst[t]?>?dst[minnode]?+?edge[minnode][i].len?||?dst[t]?==?dst[minnode]?+?edge[minnode][i].len?&&?spend[t]?>?spend[minnode]?+?edge[minnode][i].cost){??
  56. ????????????????????dst[t]?=?dst[minnode]?+?edge[minnode][i].len;??
  57. ????????????????????spend[t]?=?spend[minnode]?+?edge[minnode][i].cost;??
  58. ????????????????}??
  59. ????????????}??
  60. ????????}??
  61. ????????cout?<<?dst[enNode]?<<?setw(3)?<<?spend[enNode]?<<?endl;??
  62. ????}??
  63. ????return?0;??
  64. }??

程序運行結果如下:


使用鄰接表時,注意更新dst[],book[]時要使用鄰接表元素對應下標中的next成員,而涉及到權值加減時時需要使用鄰接表中的對應下標來取得權值;而使用鄰接矩陣就沒這么多顧慮了,因為這時候鄰接矩陣對應下標和dst[]要更新元素的下標正好一致,都是從1開始編號。

?

?

4),Bellman-Ford算法(解決負權邊,解決單源最短路徑,前幾種方法不能求含負權邊的圖)::時間復雜度O(nm),空間復雜度O(m)
主要思想:對所有的邊進行n-1輪松弛操作,因為在一個含有n個頂點的圖中,任意兩點之間的最短路徑最多包含n-1邊。換句話說,第1輪在對所有的邊進行松弛后,得到的是從1號頂點只能經過一條邊到達其余各定點的最短路徑長度。第2輪在對所有的邊進行松弛后,得到的是從1號頂點只能經過兩條邊到達其余各定點的最短路徑長度,......
以下是圖示:

此外,Bellman_Ford還可以檢測一個圖是否含有負權回路:如果在進行n-1輪松弛后仍然存在dst[e[i]] > dst[s[i]]+w[i]。算法核心代碼如下:

?

[cpp]?view plain?copy

  1. #define?inf?999999999??
  2. for(i?=?1;?i?<=?n;?i++)?dst[i]?=?inf;??
  3. dst[1]?=?0;??
  4. for(k?=?1;?k?<=?n-1;?k++){??
  5. ????for(i?=?1;?i?<=?m;?i++){??
  6. ????????if(dst[e[i]]?>?dst[s[i]]?+?w[i])??
  7. ????????????dst[e[i]]?=?dst[s[i]]?+?w[i];??
  8. ????}??
  9. }??
  10. //檢測負權回路??
  11. flag?=?0;??
  12. for(i?=?1;?i?<=?m;?i++){??
  13. ????if(dst[e[i]]?>?dst[s[i]]?+?w[i])??
  14. ????????flag?=?1;??
  15. }??
  16. if(flag)?cout?<<?"此圖含有負權回路";??

例1:對圖示中含負權的有向圖,輸出從結點1到各結點的最短路徑,并判斷有無負權回路。

?

[cpp]?view plain?copy

  1. /***先輸入n,m,分別表結點數和邊數,之后輸入m個三元組,各表起點,終點,邊權,輸出1號結點到各結點的最短路徑****/??
  2. #include?<iostream>??
  3. #include?<iomanip>??
  4. using?namespace?std;??
  5. #define?nmax?1001??
  6. #define?inf?99999999??
  7. int?n,?m,?s[nmax],?e[nmax],?w[nmax],?dst[nmax];??
  8. int?main(){??
  9. ????while(cin?>>?n?>>?m?&&?n?!=?0?&&?m?!=?0){??
  10. ????????int?i,?j;??
  11. ????????//初始化三個數組:起點數組s[],終點數組e[],權值數組w[],最短路徑數組dst[]??
  12. ????????for(i?=?1;?i?<=?m;?i++)??
  13. ????????????cin?>>?s[i]?>>?e[i]?>>?w[i];??
  14. ????????for(i?=?1;?i?<=?n;?i++)??
  15. ????????????dst[i]?=?inf;??
  16. ????????dst[1]?=?0;??
  17. ????????//使用Bellman_Ford算法??
  18. ????????for(j?=?1;?j?<=?n-1;?j++){??
  19. ????????????for(i?=?1;?i?<=?m;?i++){??
  20. ????????????????if(dst[e[i]]?>?dst[s[i]]?+?w[i])??
  21. ????????????????????dst[e[i]]?=?dst[s[i]]?+?w[i];??
  22. ????????????}??
  23. ????????}??
  24. ????????//測試是否有負權回路并輸出??
  25. ????????int?flag?=?0;??
  26. ????????for(i?=?1;?i?<=?m;?i++)??
  27. ????????????if(dst[e[i]]?>?dst[s[i]]?+?w[i])??
  28. ????????????????flag?=?1;??
  29. ????????if(flag)?cout?<<?"此圖含有負權回路\n";??
  30. ????????else{??
  31. ????????????for(i?=?1;?i?<=?n;?i++){??
  32. ????????????????if(i?==?1)??
  33. ????????????????????cout?<<?dst[i];??
  34. ????????????????else???
  35. ????????????????????cout?<<?setw(3)?<<?dst[i];??
  36. ????????????}??
  37. ????????????cout?<<?endl;??
  38. ????????}??
  39. ????}??
  40. ????return?0;??
  41. }??

程序運行結果如下:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/387043.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/387043.shtml
英文地址,請注明出處:http://en.pswp.cn/news/387043.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

20101008 搬家

剛剛系統還原了&#xff0c;把軟件啥的都裝上了&#xff0c;忙完一切&#xff0c;該整理整理照片&#xff0c;寫寫博客了&#xff08;總是如果不及時寫&#xff0c;就幾乎永遠不會寫了&#xff09;。我一貫喜歡"工欲善其事&#xff0c;必先利其器"&#xff0c;裝個wi…

ZooKeeper集群與Leader選舉

說說你對ZooKeeper集群與Leader選舉的理解&#xff1f; ZooKeeper是一個開源分布式協調服務、分布式數據一致性解決方案。可基于ZooKeeper實現命名服務、集群管理、Master選舉、分布式鎖等功能。 高可用 為了保證ZooKeeper的可用性&#xff0c;在生產環境中我們使用ZooKeeper…

JVM初探:內存分配、GC原理與垃圾收集器

JVM內存的分配與回收大致可分為如下4個步驟: 何時分配 -> 怎樣分配 -> 何時回收 -> 怎樣回收. 除了在概念上可簡單認為new時分配外, 我們著重介紹后面的3個步驟: I. 怎樣分配- JVM內存分配策略 對象內存主要分配在新生代Eden區, 如果啟用了本地線程分配緩沖, 則優先在…

02 CSS

使用 table 進行布局存在缺陷&#xff0c;而一般的布局都會采用 DIVCSS 來進行布局。 Div 它是一個html 標簽&#xff0c;一個塊級元素(單獨顯示一行)。它單獨使用沒有任何意義&#xff0c;必須結合 CSS 來使用。它主要用于頁面的布局。 Span 它是一個 html 標簽&#xff0c;…

為什么要在密碼里加點“鹽”

鹽&#xff08;Salt&#xff09; 在密碼學中&#xff0c;是指通過在密碼任意固定位置插入特定的字符串&#xff0c;讓散列后的結果和使用原始密碼的散列結果不相符&#xff0c;這種過程稱之為“加鹽”。 以上這句話是維基百科上對于 Salt 的定義&#xff0c;但是僅憑這句話還是…

一致性哈希算法 應用

互聯網創業中大部分人都是草根創業&#xff0c;這個時候沒有強勁的服務器&#xff0c;也沒有錢去買很昂貴的海量數據庫。在這樣嚴峻的條件下&#xff0c;一批又一批的創業者從創業中獲得成 功&#xff0c;這個和當前的開源技術、海量數據架構有著必不可分的關系。比如我們使用m…

(9)How to take a picture of a black hole

https://www.ted.com/talks/katie_bouman_what_does_a_black_hole_look_like/transcript 00:13In the movie "Interstellar[??nt?r?stel?(r)]星際的," we get an up-close look at a supermassive black hole. Set against a backdrop of bright gas, the black…

單個節點的緩存容量達到上限 Hash算法一致性

場景 單個節點的緩存容量達到上限&#xff0c;無法繼續單點增加內存&#xff0c;如何解決&#xff1f; 單個節點支撐的QPS達到上限&#xff0c;如何解決&#xff1f; 初步方案 增加N個緩存節點&#xff0c;為了保證緩存數據的均勻&#xff0c;一般情況會采用對key值hash&…

java學習筆記11 (構造方法 this深探)

在開發中&#xff0c;經常需要在創建對象的同事明確對象對的屬性值&#xff0c;比如一個person對象創建的時候就應該有name和age 等屬性&#xff0c;那么如何做到在創建對象的同時給對象的屬性值初始化值呢&#xff1f; 這里介紹構造方法 1 構造方法沒有返回值類型&#xff0c;…

密碼中不能包含全角字符的正則表達式

String regex "^((?![^\\x00-\\xff]).)*$"; String str "aA"; System.out.println(str.matches(regex));

編程算法 - 將排序數組按絕對值大小排序 代碼(java)

一個含有多個元素的數組&#xff0c;有多種排序方式。它可以升序排列&#xff0c;可以降序排列&#xff0c;也可以像我們以前章節說過的&#xff0c;以波浪形方式排序&#xff0c;現在我們要看到的一種是絕對值排序。對于數組A,絕對值排序滿足以下條件&#xff1a;|A[i]| < …

QT Linux打包發布

Linux&#xff1a; 1、用Release編譯&#xff1b; 2、把可執行文件(如paike)放入新建目錄中; 3、當前目錄下編寫腳本copyDependency.sh&#xff0c;把動態鏈接庫導入當前目錄&#xff1b; #!/bin/shexe"paike" #發布的程序名稱destination"/home/paike"…

CRM公海自動回收規則

企微云CRM操作指南 – 道一云|企微https://wbg.do1.com.cn/xueyuan/2568.html 銷售云 - 美洽 - 連接客戶&#xff0c;親密無間https://meiqia.com/sales-cloud 轉載于:https://www.cnblogs.com/rgqancy/p/10695466.html

三分鐘看懂一致性哈希算法

一致性哈希算法&#xff0c;作為分布式計算的數據分配參考&#xff0c;比傳統的取模&#xff0c;劃段都好很多。 在電信計費中&#xff0c;可以作為多臺消息接口機和在線計費主機的分配算法&#xff0c;根據session_id來分配&#xff0c;這樣當計費主機動態伸縮的時候&#xf…

數據結構09圖

第七章 圖 Graph 7.1 圖的定義和術語 頂點 Vertex V 是頂點的有窮非空集合&#xff0c;頂點數 |V| n VR 兩個頂點之間關系的集合&#xff0c;邊數 |VR| e 有向圖 Digraph <v, w> Arc v Tail / Inital node w Head / Terminal node 無向圖 Undigraph <v, w> 必…

JVM調優-GC參數

一、Throughput收集器(吞吐量) -XX:UseParallelGC -XX:UseParallelOldGC *參數調整&#xff1a;通過調整堆大小&#xff0c;減少GC停頓時間&#xff0c;增大吞吐量 增強堆大小可以減少Full GC頻率&#xff0c;但卻會增加停頓時間 1.手動調整 -Xmn -Xms -XX:NewRatioN 手動指…

aspnetcore源碼學習(一)

---恢復內容開始--- 筆者從事netcore相關項目開發已經大半年了&#xff0c;從netcore 1.0到現在3.0大概經過了3年左右的時間&#xff0c;記得netcore剛出來的時候國內相關的學習資料缺乏&#xff0c;限制于外語不大熟練的限制國外的相關書籍看起來相當吃力&#xff0c;于是在當…

評估一個垃圾收集(GC)

在實踐中我們發現對于大多數的應用領域&#xff0c;評估一個垃圾收集(GC)算法如何根據如下兩個標準&#xff1a; 吞吐量越高算法越好暫停時間越短算法越好 首先讓我們來明確垃圾收集(GC)中的兩個術語:吞吐量(throughput)和暫停時間(pause times)。 JVM在專門的線程(GC threads…

python數據分析常用包之Scipy

Scipy轉載于:https://www.cnblogs.com/jacky912/p/10697853.html

docker容器狀態跟蹤及疑惑

一、 1 def status_test():2 container client.containers.create("comp")3 print ("create: ", container.status)4 container.start()5 print ("start: ", container.status)6 container.pause()7 print ("paus…