每次找到離源點最近的乙個頂點,然後以該頂點為中心向下擴充套件,最終得到源點到其餘所有點的最短路徑。
說明:dis陣列儲存離源點的所有點的最短路徑,比如源點是1,dis[2]=3,表示頂點2離源點的最短路徑為2
執行步驟:
1.將所有點的頂點分為兩部分:已知最短路徑集合p和未知最短路徑的集合q。最開始,已知最短路徑的頂點集合p只有源點乙個頂點。我們這裡用乙個book陣列來記錄哪些點在集合p中。例如當對於某個頂點i,如果book[i]為true則表示這個頂點在集合p中,如果book[i]為false則表示在集合q中。
2.設定源點s到自己的最短路徑為0即dis[s]=0;若存在源點能直接到達頂點i,則把dis[i]設為e[s][i].同時把其他其他所有(源點不能直接到達的)頂點的最短路徑設為無窮大
3.在集合q的所有頂點中選擇乙個離源點s最近的頂點u(即dis[u]最小)加入到集合p.並考察所有以點u為起點的邊,對每一條邊進行鬆弛操作。例如存在一條從u到v的邊,那麼可以通過將邊u→v新增到尾部來拓展一條從s到v的路徑,這條路徑的長度是dis[u]+e[u][v].如果這個值比目前已知的dis[v]的值最小,我們可以用新值來替代當前dis[v]中的值
4.重複第三步,如果集合q為空,演算法結束。最終dis陣列中的值就是源點到所有頂點的最短路徑
輸入我們採用鄰接矩陣:
用e陣列來儲存圖
scanf
("%d %d"
,&n,
&m,&cnt)
;//n個頂點,m條邊,cnt表示源點
for(
int i=
1;i<=n;i++
)else}}
int t1,t2,t3;
for(
int i=
1;i<=m;i++
)
初始化dis陣列(也就是步驟2):
for
(int i=
1;i<=n;i++
)
初始化book陣列:
這裡我開到了全域性變數,所以所有值預設為false(還未求出最短路徑)
我們只需要將源點的book賦值為true即可,表示源點已求出最短路徑
book[cnt]
=true
;//初始化book陣列
核心演算法:
//dijkstra演算法核心
//實現找出離源點最近的點
for(
int i=
1;i<=n-
1;i++)}
book[u]
=true
;//已經找出來離遠點最近的點,將此點設為訪問過
//以下實現鬆弛操作
for(
int v=
1;v<=n;v++)}
}}
完整**:
/*
測試資料 :第一行n,m,cnt,接下來是m條邊
6 9 1
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
*/#include
int e[10]
[10];
//鄰接矩陣存放圖
int dis[10]
;//用來記錄所有點離原點的最短路徑
bool book[10]
;//記錄點有沒有被訪問過
int n,m,min,inf=
99999999
,cnt;
intmain()
else}}
int t1,t2,t3;
for(
int i=
1;i<=m;i++
)for
(int i=
1;i<=n;i++
)/*for( i=1;i<=n;i++)printf("\n");
}*/book[cnt]
=true
;//初始化book陣列
int min,u;
//dijkstra演算法核心
for(
int i=
1;i<=n-
1;i++)}
book[u]
=true
;for
(int v=
1;v<=n;v++)}
}}for(
int i=
1;i<=n;i++
)return0;
}
該演算法大量的時間花在前期尋找最近的點這一步,其實可以直接使用小頂堆進行優化
/*
測試資料
6 9 1
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
0 1 8 4 13 17
*/#include
#include
#include
#include
using
namespace std;
const
int inf =
2147483647
;int n,m,start,dis[
10005
],vis[
10005];
struct node};
vector ve[
10005];
//鄰接表存圖
priority_queueint,
int>
,vectorint,
int>
>
,greaterint,
int>
>
> que;
//小頂堆
intmain()
//初始化dis
for(
int i=
1;i<=n;i++)
dis[start]=0
;//初始化佇列
que.
push
(make_pair(0
,start));
//dijkstra演算法
while
(!que.
empty()
)}}for
(int i=
1;i<=n;i++
)return0;
}
單源最短路 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演算法
本文 自王陸的文字,僅作學習使用。dijkstra 迪傑斯特拉 演算法是典型的單源最短路徑演算法,用於計算乙個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。問題描述 在無向圖 g v,e 中,假設每條邊 e i 的長度為 w i 找到由頂點 v0 到...