Djikstra算法思路
Djikstra算法其實前面總結過,這次有了新收穫.
Djikstra算法有點動態規劃的感覺,後一個結果根前一個結果有關.3個數組很重要,一個是dist數組,也就是頂點之間的距離,一個是visit,記錄頂點是否已經被訪問過,一個是path,記錄最短路徑.
一開始我寫出來的Djisktra算法是模仿書上的,後來看到了更加精簡的版本,主要是初始化的不同.過程還是類似,過程:
Dijkstra() {
初始化;
for(循環n次) {
u = 使dis[u]最小的還未被訪問的頂點的編號;
記u爲確定值;
for(從u出發能到達的所有頂點v){
if(v未被訪問 && 以u爲中介點使s到頂點v的最短距離更優)
優化dis[v];
}
}
}
精簡版的初始化中,dist數組除了源點外其他全部初始化爲整型的最大值,這是爲了方便在dist數組中找最小值,visit數組全部置爲false,這是爲了在第一次迭代的時候找到源點,path的每個元素置爲自己的下標.接下來就差不多了
優化
從源點出發到某一點的最短路徑可能有多條,爲了解決這個問題,可以將path數組設爲二維數組,爲了方便的加入數據,可以將數組的元素設爲vector.
代碼
#include <iostream>
#include <climits>
#include <vector>
using namespace std;
int n = 7;
const int INF = INT_MAX;
int graph[7][7] = {
{0, 4, 6, 6, INF, INF, INF},
{INF, 0, 1, INF, 7, INF, INF},
{INF, INF, 0, INF, 6, 4, INF},
{INF, INF, 2, 0, INF, 5, INF},
{INF, INF, INF, INF, 0, INF, 6},
{INF, INF, INF, INF, 1, 0, 8},
{INF, INF, INF, INF, INF, INF, 0}
};
void dfs(int v,vector<int> *path,int s) {
cout<<v<<" ";
if(v==s) {
return;
}
for(int i=0; i<path[v].size(); i++) {
dfs(path[v][i],path,s);
}
}
void djikstra(int s) {
bool visit[n] = {false};
vector<int> path[n];
int dist[n];
fill(dist,dist+n,INF);
dist[s] = 0;
path[s].push_back(s);
for(int i=0; i<n; i++) {
int mdis = INF;
int u = -1;
for(int j=0; j<n; j++) {
if(visit[j]==false&&dist[j]<mdis) {
mdis = dist[j];
u = j;
}
}
if(u==-1)
return;
visit[u] = true;
for(int j=0; j<n; j++) {
if(visit[j]==false&&graph[u][j]!=INF&&graph[u][j]+dist[u]<dist[j]) {
dist[j] = graph[u][j]+dist[u];
path[j].clear();
path[j].push_back(u);
} else if(visit[j]==false&&graph[u][j]!=INF&&graph[u][j]+dist[u]==dist[j]) {
path[j].push_back(u);
}
}
}
for(int i=0; i<n; i++) {
cout<<visit[i]<<" ";
}
cout<<"\n";
for(int i=0; i<n; i++) {
cout<<dist[i]<<" ";
}
cout<<"\n";
dfs(6,path,s);
}
int main() {
djikstra(0);
return 0;
}