前幾天研究的bellman_ford演算法雖然可以算負權,可是時間複雜度高達o(nm),即使是採用了佇列優化,也有可能被網格圖卡回o(nm),所以今天我們就來研究乙個新的,更快的,但同時只能在正權圖上執行的演算法:dijkstra(樸素dijkstra演算法)
我們首先需要以下幾個陣列:dist,vis,用鄰接矩陣需要g,鄰接表則需要v,w,head,nxt
演算法步驟:
1)將源點距離初始化為0,其它點為正無窮inf
2)經過n次如下操作,得到源點離其它點的最短距離:
1、選擇乙個未擴充套件的點k,滿足dist[k]是未擴充套件節點中離源點距離最小的;
2、對k進行永久標號
3、以k為中間點修改源點到其它點的最短路距離
時間複雜度o(n2),由於所有邊權都為正,從而保證了演算法的正確性。
dijkstra堆優化(鄰接表+優先佇列)
1 #include2 #include3view code#define inf 336860180
4using
namespace
std;
5int n,m,x,y,w,map[1000][1000],minn,dist[1000
],t;
6bool pd[1000];7
intmain()816
for(int i=1;i<=m;i++)
1721 dist[1]=0
;22 pd[1]=1;23
for(int i=1;i<=n;i++)
2433
}34 pd[t]=1;35
for(int j=1;j<=n;j++)
3639}40
for(int i=1;i<=n;i++)
4146
return0;
47 }
由於每次查詢最短的點浪費大量時間,我們可以用優先佇列進行查詢,用pair記錄,第一維記錄最短距離,第二維記錄點的編號,建立乙個小根堆,每次取堆頂擴充套件即可。時間複雜度降為o((n+m)logm),參考程式如下:
1 #include2 #include3 #include4 #include5view codeusing
namespace
std;
6 typedef pair
long,long
long>p;
7long
long n,m,s,dist[100001],v[200005],w[200005],nxt[200005],head[200005
],cnt,x,y,z;
8bool vis[100001];9
void add(long
long a,long
long b,long
long
c)10
16void dijkstra(int
s)1736}
37}38}
39int
main()
4047
dijkstra(s);
48for(int i=1;i<=n;i++)
4952
return0;
53 }
Dijkstra演算法詳解
在解決單源點最短路徑的問題時,常常用到經典的dijkstra演算法,其演算法的本質思想是 按路徑長度遞增依次產生最短路徑。下面給出演算法的大致流程 1.初始化所有結點並將起始點設為標記,進入以下迴圈 2.在到達某點的最短路徑中找最小且未標記的點 可以用一維陣列表示 如 陣列下標 0 1 2 3 4 ...
Dijkstra演算法詳解
dijkstra演算法是由e.w.dijkstra於1959年提出,又叫迪傑斯特拉演算法,它應用了貪心演算法模式,是目前公認的最好的求解最短路徑的方法。演算法解決的是有向圖中單個源點到其他頂點的最短路徑問題,其主要特點是每次迭代時選擇的下乙個頂點是標記點之外距離源點最近的頂點。但由於dijkstra...
Dijkstra演算法詳解
迪傑斯特拉 dijkstra 演算法是典型最短路徑演算法,用於計算乙個節點到其他節點的最短路徑。它的主要特點是以起始點為中心向外層層擴充套件 廣度優先搜尋思想 直到擴充套件到終點為止 通過dijkstra計算圖g中的最短路徑時,需要指定起點s 即從頂點s開始計算 此外,引進兩個集合s和u。s的作用是...