嘗試著用最簡單明了的方法解釋。。。
問題:
給你一幅圖,求起點到終點的最短路徑。
做法:
假設d[i]表示起點到i的最短路徑,那麼我們的目的就是求出所有的d[i],然後輸出 d[終點]。
一開始我們先設所有的d[i] = inf(一個很大的數) ,然後開搞。
首先,我們邁出我們勇敢的第一步,d[s] = 0,(s為起點), 從s出發,到達附近的點,附近點的最短路徑都可以被更新了,更新完附近的點後,我們將s刪除,因為s已經更新不了別的點了,而且s也不可能被別的點更新了,下次訪問到的時候直接跳過就好了。
現在s點附近的點的最短距離都已經被更新了,現在我們需要再找一個已經確定最短路徑的點。
到底找哪個點呢????
YY一下,找d[i]最小的i行不行 ?
行!為什嗎???
想想就知道了嘛。。i點的d[i]最小,他的最短路還可能被繼續更新麼 ? 因為其他d[i]都比他大,所以不管其他點怎麼繞到i點,都不可能更新d[i]了。
所以我們的演算法就出來了
每次找到d[i]最小的i,而且這個i沒有被刪除,用這個i去更新他周圍的最短路徑,接著把i刪除。
重複上述操作直到所有的點被刪除了。。那麼我們的最短路就求好了。
下面是oj 上某題的代碼。。
hdu 2544
#include <cstdio>#include <cstring>const int N = 110;const int inf = 99999999;int cost[N][N];int d[N];bool deleted[N];int n , m;//假設點從1開始//初始化矩陣cost,以及距離標號dvoid Prepare(int s) {for(int i = 1; i <= n; i++){cost[i][i] = 0;for(int j = i + 1; j <= n; j++){cost[i][j] = cost[j][i] = inf;}}for(int i = 1; i <= n; i++) d[i] = inf;d[s] = 0;for(int i = 1; i <= n; i++) deleted[i] = false;}int Shortest_Path(){while(true){int decided = -1;for(int i = 1; i <= n; i++) if(!deleted[i]){if(decided == -1 || d[i] < d[decided]) decided = i;}if(decided == -1) break;//可以輸出看一下哪些點的最短路依次確定了//printf("decided=%d\n",decided);for(int i = 1; i <= n; i++){if(d[decided] + cost[decided][i] < d[i]){d[i] = d[decided] + cost[decided][i];}}deleted[decided] = true;}return d[n];}int main(){int a,b,c;while(scanf("%d%d",&n,&m),(n||m)){Prepare(1);for(int i = 0; i < m; i++){scanf("%d%d%d",&a,&b,&c);if(c < cost[a][b]){cost[a][b] = c; cost[b][a] = c;}}printf("%d\n",Shortest_Path());}}