學習dijkstra已經一週了,學完之後沒有溫習,以至於今天做題的時候忘了。
當做溫習一下吧。
講一講dijkstra的主要做法吧。
我們用一個數組s 去存儲最短路徑上的點(實際上還有標記某點是否被訪問的作用)。
還需要用一個dis數組,去儲存從起點到某個點的最小距離。(dis[ j ] 就表示從起點到 j 的最短距離)。
如果要求輸出路徑,我們還可以用一個poineer數組,去記錄最短路上某個點的先驅頂點。(其實最好是用棧存放,便於打印路徑)
設起點爲start , 圖用鄰接矩陣 matrix[ ][ ] 儲存。
我們從起點出發,首先將所有與起點相連的邊存在dis數組裏。(毫無疑問,起點到 i 的最短距離就是 matrix[ start ][ i ])
然後我們尋找與start相連的最短路。假設爲 k, 然後我們以 k 爲中間點尋找最短路。若從 start -> k + k ->j < start ->j, 我們就更新start -> j 的最小距離 。
重複上一步,直到所有頂點都被標記。
此時我們得到的dis數組是一個從 start 出發,到其他所有頂點的最短路。
void dijkstra(int start)//int matrix[][], int poineer[][], int dis[]->這些都可以設爲全局變量, int f,f爲頂點數
{
for(int i = 1; i <= f; i++)
{
dis[i] = matrix[start][i];
s[i] = false;
if(matrix[start][i] < INF)
{
poineer[i] = start;
}
else
poineer[i] = -1;
}
int pos;
s[start] = 1;
dis[start] = 0;
for(int i = 1; i < f; i++)
{
int min = INF;
for(int j = 1; j <= f; j++)
{
if(!s[j] && dis[j] < min)
{
pos = j;
min = dis[j];
}
}
s[pos] = true;
for(int j = 1; j <= f; j++)
{
if(!s[j] && matrix[pos][j] < INF)
if(matrix[pos][j] + dis[pos] < dis[j])
{
poineer[j] = pos;
dis[j] = dis[pos] + matrix[pos][j];
}
}
}
}
接下來講講一些注意事項:
1. 給出 從 i - > j 的直接路可能不只一條,我們在儲存的時候需要存儲最小的那條路。
2.需要進行特殊判斷:(1)起點和終點可能根本沒有出現(hdu 2112),這個當然是不可達的。(2)起點和終點相同,直接輸出0。
3.注意的有向圖還是無向圖。
4.dijkstra不能處理有負權邊的圖。