Djikstra溫故知新

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;
}

多條最短路徑計算最小邊權,點權,最短路徑數目

點這裏

??正文結束??
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章