dijkstra是一種單源最短路徑演算法,即求乙個點到其他點的最短路。不能處理負邊權。
最近某種廣為人知的演算法頻繁被卡,讓dijkstra逐漸成為了主流,甚至在初賽中鞭屍了spfa(?
dijkstra效率還是不錯的,而且不容易被卡。
用dis陣列儲存最短路徑。初始化時,dis[s]設定為0(s為起點),其他無窮大。
列舉點i,每次從i能夠到達的點中,選出權值最小的乙個mpl(min place 個人叫法),把dis[mpl]直接設定為權值。可以證明,這就是最短的路徑。
證明:若不是,則必有點k,能使
s->k+k->mpl < s->mpl
由權值最小得 s->mpl < s->k 明顯矛盾
(我居然沒寫易證!
再列舉mpl到達的點k,若mpl->k+dis[mpl] > dis[k] 則更新dis[k]。專業術語叫做:鬆弛。
以此類推,更新完所有的點,演算法結束。複雜度o(n2)
**:
#include#include#include
using
namespace
std;
//gdt tql orz
struct
edge g[
500005];//
前向星int dis[500005],gdt[500005],n,m,s,u,v,w,ne=0;//
gdt就是head陣列。此處為玩梗qwq
inline
void add(int
from,int to,int
d) //
前向星建邊
inline
void
dijkstra() ;
dis[s]=0
;
for(register int i=1;i<=n;i++)
}//選出權值最小的點
vis[mpl]=1;//
此節點已被拓展,也就是變為白點(你們可能會從奇奇怪怪
//的演算法書中得到這種說法)。
for(register int now=gdt[mpl]; now; now=g[now].next)
}}int
main()
dijkstra();
for(int i=1; i<=n; i++)
return0;
}
所謂堆,實際相當於乙個優先佇列。
每次把點入隊,使用時直接可以訪問離s距離最小的。
具體實現時,會用stl中的priority_queue(優先佇列)。而且,乙個點需要乙個位址(訪問)和乙個距離s的最短距離(比較、更新最短路徑)。
**:
#include#include#include
#include
using
namespace
std;
//gdt tql orz
struct
edge
g[500005
];struct
node
;bool
operator
<(node n1,node n2)
//優先佇列維護時需要比較,而結構體無法直接比較,使用過載運算子。
int dis[500005],gdt[500005],n,m,s,u,v,w,ne=0
;inline
void add(int
from,int to,int
d)inline
void
dijkstra()
; dis[s]=0
; priority_queue
pq; temp.k=s;
temp.v=0
; pq.push(temp);
//第乙個點更新起點
while(!pq.empty())}}
}int
main()
dijkstra();
for(int i=1; i<=n; i++)
return0;
}
三、關於spfa
如果乙個圖沒有負邊權,那就一定會卡你的spfa。
Dijkstra演算法 學習筆記
dijkstra演算法用於求最短路徑,原理的話可以去網上搜搜,有一些講得還是比較清楚的。筆者是在學opencv的時候接觸到的,不過 寫出來似乎跟c 關係比較大,無妨,會用就好。感謝轉 最短路徑 dijkstra演算法和floyd演算法 和原 dijkstra演算法 matlab 這兩篇博文的作者。本...
Dijkstra演算法學習
dijkstra演算法是求解有向圖最短路徑的經典演算法,計算從乙個指定的初始結點到其他各個結點最短路徑。它的理論基礎就是一條最短路徑的子路徑也一定是最短的。實現如下 將所有結點分為兩個集合,乙個命名為s集,乙個命名為u集。s集中的點是我們已知其最短路徑的點,u集中的點是我們還未知其最短路徑的點。因此...
演算法學習整理 一 Dijkstra
假設構建的是一副無向圖 圖中有0 6 7個點,每段線表示從乙個點到另乙個點的值 dijkstra演算法的目的是找到乙個點到另乙個點的最短路徑 假設已經構建好了圖的關係,並選取了起始點a1 思路 初始化兩個點集合s和u,s包括起點a1,u包括剩餘點,遍歷計算s中點到u中點的最短距離,不相鄰 連線的距離...