輸入:
本題目包含多組資料,請處理到檔案結束。
每組資料第一行包含兩個正整數n和m(0輸出:
對於每組資料,請在一行裡輸出最短需要行走的距離。如果不存在從s到t的路線,就輸出-1
用於解決最短路徑問題的演算法被稱做「最短路徑演算法」, 有時被簡稱作「路徑演算法」最常用的路徑演算法有四種:
1.dijkstra(迪傑斯特拉)------------解決單源最短路問題。(貪心的思想)----條件:非負權值。
2.bellman-ford(貝爾曼-福特)--------解決單源最短路問題。(逐個遍歷每一條邊)
3.floyd(弗洛伊德)---------------解決全源最短路問題。(dp的思想)
4.spfa(shortest path faster algorithm)-----------解決單元最短路問題。(佇列實現,是bellman-ford演算法的一種改進)
方法一:bellmanford,
bellman-ford演算法可以大致分為三個部分
第一,初始化所有點。每乙個點儲存乙個值,表示從原點到達這個點的距離,將原點的值設為0,其它的點的值設為無窮大(表示不可達)。
第二,進行迴圈,迴圈下標為從1到n-1(n等於圖中點的個數)。在迴圈內部,遍歷所有的邊,進行鬆弛計算。
第三,遍歷途中所有的邊(edge(u,v)),判斷是否存在這樣情況:
d(v) > d (u) + w(u,v)
則返回false,表示途中存在從源點可達的權為負的迴路。
bellman-ford演算法可以解決圖中有權為負數的邊的單源最短路徑問題。
#include
#include
#include
#define m 999999
int map[
205][
205];
int vis[
205],dis[
205];
int n,m;
int s,t;
void
bellmanford
()//美國數學家理查德•貝爾曼(richard bellman, 動態規劃的提出者)和小萊斯特•福特(lester ford)發明}}
}if(dis[t]!=m)
printf
("%d\n"
,dis[t]);
else
printf
("-1\n"
);}intmain
()while
(m--)
scanf
("%d%d"
,&s,&t);
bellmanford
();}
return0;
}
方法二:迪傑斯特拉演算法 ------遍歷經過的節點多,效率低---------要非負權值
1.從v-u中選擇使dist[i]值最小的頂點i,將i加入到u中;
2.更新與i直接相鄰頂點的dist值。(dist[j]=min)
3.知道u=v,停止。
#include
#include
#include
#define m 999999
int map[
205][
205];
int vis[
205],dis[
205];
int n,m;
int s,t;
void
dijkstra
()//迪傑斯特拉演算法
} vis[flag]=1;
for(j=
0; j(dis[t]!=m)
printf
("%d\n"
,dis[t]);
else
printf
("-1\n"
);}intmain
()while
(m--)
scanf
("%d%d"
,&s,&t);
dijkstra
();}
return0;
}
方法三:floyd(弗洛伊德)真不是很懂。
floyd-warshall演算法的原理是
動態規劃。
設di,j,k
為從i到j
的只以(1..k)集合中的節點為中間節點的最短路徑的長度。
若最短路徑經過點k,則d
i,j,k
= di,k,k − 1 + d
k,j,k − 1
;若最短路徑不經過點k,則d
i,j,k
= di,j,k − 1
。因此,d
i,j,k
= min(d
i,k,k − 1 + d
k,j,k − 1,d
i,j,k − 1)
#include
#include
#include
#define m 9999999
int map[
205][
205];
int n,m;
int s,t;
void
floyd
()int
main
()while
(m--)
scanf
("%d%d"
,&s,&t);
floyd
();}
return0;
}
方法四:
就是在bellman_ford演算法的基礎上加上佇列實現。
佇列中的元素出隊後還可以再進隊。
#include
#include
#include
#define m 9999999
int map[
205][
205],q[
205];
int dis[
205],vis[
205];
int n,m;
int s,t;
void
spfa()}
} vis[p]=0;
}if(dis[t]!=m)
printf
("%d\n"
,dis[t]);
else
printf
("-1\n"
);}intmain
()while
(m--)
scanf
("%d%d"
,&s,&t);
spfa
();}
return0;
}
最短路的幾種演算法
單源無負權最短路 dijkstra 多源無負權最短路 floyd 單源負權最短路 bellman ford,spfa 以hdu 2544為例 dijkstra include using namespace std typedef pair int,int par const int maxv 1e...
hdu2544 最短路 幾種最短路演算法實現
floyd warshall演算法 時間複雜度o v 3 一般不用 演算法模板 include include include using namespace std const int max v 110 const int inf 0x3f3f3f3f int d max v max v d u...
最短路的幾種常用演算法
hdu1874 暢通工程續 陳年水題,老少皆宜,最短路的入門作業 但是換個刷法,會更有意思 最短路的 floyd 演算法 include include define find min a,b a最短路dijkstra演算法的 鄰接陣實現 include include define find mi...