迪傑斯特拉(Dijkstra)最短路徑算法


回顧算法思路:

該算法用於求指定頂點A到其余每個頂點的最短路徑;

將頂點分為兩部分S、U,S部分是已經確定最短路徑的點,另一部分U是尚未確定最短路徑的點,

確保目前狀態X的所有路徑是從集合S到U某一點的最短路徑(即路徑只有終點在U中,其余頂點均在S中;

1、在所有路徑中選取最短的路徑所對應的頂點加入到S中(該條路徑已經是確定的最短路徑;

2、由於S中加入了一個頂點B,更新其他路徑以達到狀態X

循環1、2,確保所有的點都已加入S,結束;

#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;

struct Dis {
    string path;//存儲路徑
    int value;//存儲路徑的值
    bool visit;//是否加入S中
    Dis() {//構造函數
        visit = "false";
        value = INT_MAX;
        path = "";
    }
};

struct Graph_DG {
    int vexnum;//頂點的數量
    int arcnum;//邊的數量
    int **a;//存儲圖即每對頂點的權重
    Dis  *dis;
};

int main()
{
    cout << "本算法計算的是從無向圖中一個指定點到其他任何一點"<<
        "的最短距離,以及對應的路徑" << endl;
    Graph_DG DG;
    /*創建圖*/
    cout << "請輸入頂點數和邊數:";
    cin >> DG.vexnum >> DG.arcnum;
    DG.a = new int *[DG.vexnum];
    for (int i = 0; i < DG.vexnum; i++)
    {
        DG.a[i] = new int[DG.vexnum];
        for (int j = 0; j < DG.vexnum; j++)
        {
            DG.a[i][j] = INT_MAX;
            if (i == j)
                DG.a[i][j] = 0;
        }
    }

    cout << "請輸入每條邊的起始點,終點和對應的權值" << endl;
    for (int i = 0; i < DG.arcnum; i++)
    {
        int x, y;
        cin >> x >> y;
        cin >> DG.a[x][y];
        DG.a[y][x] = DG.a[x][y];
    }

    int start;
    cout << "請輸入該指定點:";
    cin >> start;
    DG.dis = new Dis[DG.vexnum];
    
    for (int i = 0; i < DG.vexnum; i++)
    {
        DG.dis[i].value = DG.a[start][i];
        DG.dis[i].visit = false;
        DG.dis[i].path = to_string(start) + "-->" + to_string(i);
    }
    //使用迪傑斯特拉算法
    int count = 1;
    DG.dis[start].visit = true;//將起點加入S中
    while (count < DG.vexnum)
    {
        int min = INT_MAX;
        int temp;
        for (int i = 0; i < DG.vexnum; i++)
        {
            if (DG.dis[i].value <= min && DG.dis[i].visit == false)
            {//只要有未加入的點,就找出距離最短的點加入
                min = DG.dis[i].value;
                temp = i;
            }
        }
        count++;
        DG.dis[temp].visit = true;

        //更新距離
        for (int i = 0; i < DG.vexnum ; i++)
        {
            if (DG.dis[i].visit == false)
            {
                if (DG.a[temp][i] < INT_MAX && DG.dis[i].value < INT_MAX && DG.dis[temp].value + DG.a[temp][i] < DG.dis[i].value)
                {
                    DG.dis[i].path = DG.dis[temp].path + "-->" + to_string(i);
                    DG.dis[i].value = DG.dis[temp].value + DG.a[temp][i];
                }
            }
        }
    }

    //打印輸出
    for (int i = 0; i < DG.vexnum; i++)
    {
        if(DG.dis[i].value < INT_MAX)
            cout <<"距離:"<< DG.dis[i].value <<"最短路徑:"<< " , "<< DG.dis[i].path << endl;
        else
            cout << "距離:" << "infinite , " << "最短路徑:" << DG.dis[i].path << endl;
    }
    //非內部數據類型手動釋放內存
    delete[] DG.dis;
    //二維數組釋放內存的方法
    for (int i = 0; i < DG.vexnum; i++)
        delete[] DG.a[i];
    delete[] DG.a;
    system("pause");
    return 0;
}

 運行結果如下:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM