單源最短路 Dijkstra演算法

2022-01-26 02:19:47 字數 2618 閱讀 5742

本文**自王陸的文字,**僅作學習使用。

dijkstra(迪傑斯特拉)演算法是典型的單源最短路徑演算法,用於計算乙個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。

問題描述:在無向圖 g=(v,e) 中,假設每條邊 e[i] 的長度為 w[i],找到由頂點 v0 到其餘各點的最短路徑。(單源最短路徑)

設g=(v,e)是乙個帶權有向圖,把圖中頂點集合v分成兩組,第一組為已求出最短路徑的頂點集合(用s表示,初始時s中只有乙個源點,以後每求得一條最短路徑 , 就將加入到集合s中,直到全部頂點都加入到s中,演算法就結束了),第二組為其餘未確定最短路徑的頂點集合(用u表示),按最短路徑長度的遞增次序依次把第二組的頂點加入s中。在加入的過程中,總保持從源點v到s中各頂點的最短路徑長度不大於從源點v到u中任何頂點的最短路徑長度。此外,每個頂點對應乙個距離,s中的頂點的距離就是從v到此頂點的最短路徑長度,u中的頂點的距離,是從v到此頂點只包括s中的頂點為中間頂點的當前最短路徑長度。

a.初始時,s只包含源點,即s=,v的距離為0。u包含除v外的其他頂點,即:u=,若v與u中頂點u有邊,則正常有權值,若u不是v的出邊鄰接點,則權值為∞。

b.從u中選取乙個距離v最小的頂點k,把k,加入s中(該選定的距離就是v到k的最短路徑長度)。

c.以k為新考慮的中間點,修改u中各頂點的距離;若從源點v到頂點u的距離(經過頂點k)比原來距離(不經過頂點k)短,則修改頂點u的距離值,修改後的距離值的頂點k的距離加上邊上的權。

d.重複步驟b和c直到所有頂點都包含在s中。

執行動畫過程如下圖

**太快可以看下面的例子:

重點需要理解這句拗口的」按最短路徑長度的遞增次序依次把第二組的頂點加入s中。在加入的過程中,總保持從源點v到s中各頂點的最短路徑長度不大於從源點v到u中任何頂點的最短路徑長度」

實際上,dijkstra 演算法是乙個排序過程,就上面的例子來說,是根據a到圖中其餘點的最短路徑長度進行排序,路徑越短越先被找到,路徑越長越靠後才能被找到,要找a到f的最短路徑,我們依次找到了

a –> c 的最短路徑 3

a –> c –> b 的最短路徑 5

a –> c –> d 的最短路徑 6

a –> c –> e 的最短路徑 7

a –> c –> d –> f 的最短路徑 9

**為什麼dijkstra 演算法不適用於帶負權的圖? **

就上個例子來說,當把乙個點選入集合s時,就意味著已經找到了從a到這個點的最短路徑,比如第二步,把c點選入集合s,這時已經找到a到c的最短路徑了,但是如果圖中存在負權邊,就不能再這樣說了。舉個例子,假設有乙個點z,z只與a和c有連線,從a到z的權為50,從z到c的權為-49,現在a到c的最短路徑顯然是a –> z –> c

再舉個例子:

在這個圖中,求從a到c的最短路,如果用dijkstra根據貪心的思想,選擇與a最接近的點c,長度為7,以後不再變化。但是很明顯此圖最短路為5。歸結原因是dijkstra採用貪心思想,不從整體考慮結果,只從當前情況考慮選擇最優。

#include#include#define inf 0x3f3f3f3f

int map[110][110],dis[110],visit[110];

/*關於三個陣列:map陣列存的為點邊的資訊,比如map[1][2]=3,表示1號點和2號點的距離為3

dis陣列存的為起始點與每個點的最短距離,比如dis[3]=5,表示起始點與3號點最短距離為5

visit陣列存的為0或者1,1表示已經走過這個點。

*/int n,m;

int dijstra()

visit[1]=1;

dis[1]=0;

for(i=1; idis[j])

}visit[pos]=1;//表示這個點已經走過

for(j=1; j<=n; ++j)

}return dis[n];

}int main()

}int a,b,c;

for(i=1; i<=m; ++i)

t;int n;///n為點數

vectorq[500001];///鄰接表儲存圖的資訊

int dis[500001];///距離

int vis[500001];///標記陣列

void dijkstra(int start,int end)

len=q[start].size();

for(i=0; iq[pos][j].power+dis[pos])}}

printf("%d\n",dis[end]);

}int main()

for(i=0; i

scanf("%d%d",&a,&b);///輸入起點與終點

dijkstra(a,b);

}return 0;

}

單源最短路 Dijkstra演算法

前提 沒有負邊 如果有負邊,可以用此方法檢查是否有負圈 const max v max v 表示邊的權重值 d max v 儲存從起點到每個點的總權重值 bool used max v 表示當前點是否已經訪問完畢 思想 找到乙個已經確定最短距離的點,更新跟它相鄰的點,之後這個點就不用關心了。起點最短...

單源最短路演算法 Dijkstra

dijkstra演算法是單源最短路演算法,可以求解不帶負權邊的圖中,從源點s到其它所有點的最短路。時間複雜度近似o n 2 可以用堆優化。一般用鄰接表,也可用鄰接矩陣。在稠密圖上會有較好的效能表現。include include using namespace std int s,t,n,m,las...

單源最短路 Dijkstra演算法

返回上一級 author 張海拔 update 2015 03 11 link dijkstra演算法 總的來說 演算法從開始節點,按照總路徑權值非遞減的順序去搜尋所有路徑,直到發現指定的終止節點或發現全部節點為止。我們先看看演算法的步驟 演算法是遞推的 先設d begin 0,d others i...