Dijkstra算法那--賦權最短路徑

相對於無權最短路徑,賦權最短路徑多了一個成員know來標記頂點是否已知。從未知的頂點中找到路徑最短的頂點,標記爲已知,然後如果它的未知鄰接頂點距離dw大於dv+Cv,w,則更新dw

這裏寫圖片描述

頭文件

#include <vector>
#include <map>
#include <iostream>
static const int MAX=10000;
using namespace std;

class Graph
{
public:
    explicit Graph(int vertexNum):v(vertexNum+1)
    {
        for(auto x:v)
        {
            x.dist=MAX;
            x.path=nullptr;
            x.adjacentList=map<Vertex*,int>{};
            x.know=false;
        }
        initialVertex=0;

    }


    void setVertex(int vertexIndex,const map<int,int> & adjacentIndex)
    {
        //創建鄰接表
        for(auto x:adjacentIndex)
        {
            v[vertexIndex].adjacentList[&v[x.first]]=x.second;
        }
    }

    void weighted(int initialVer);

    void printPath(int end)
    {
        if(v[end].dist==MAX)
            std::cout<<"V"<<end<<" can not be reached by V"<<initialVertex<<std::endl;
        else
        {
            std::cout<<"shortest length from V"<<initialVertex<<" to V"
            <<end<<" is "<<v[end].dist<<std::endl;

            printPath(&v[end]);
            std::cout<<std::endl;
        }
    }


private:
    struct Vertex
    {
        int dist;                               //距離
        map<Vertex*,int> adjacentList;          //鄰接表(鄰接頂點以及之間的權重)
        Vertex* path;                           //上一個節點
        bool know;


        explicit Vertex(const map<Vertex*,int> & adList=map<Vertex*,int>{})
        {
            dist=MAX;
            path=nullptr;
            adjacentList=adList;
            know=false;
        }
    };

    std::vector<Vertex> v;
    int initialVertex;


    void printPath(Vertex* ver);

};

cpp文件

#include "Graph.hpp"



void Graph::weighted(int initialVer)
{
    initialVertex=initialVer;
    v[initialVer].dist=0;

    for(int i=1;i<v.size();++i)//找到所有頂點
    {
        //找到最小頂點
        int firstUnknow=1;
        while (v[firstUnknow].know){++firstUnknow;}

        int minV=firstUnknow;
        for(int j=firstUnknow+1;j<v.size();++j)
        {

            if(!v[j].know&&v[j].dist<v[minV].dist)
                minV=j;

        }
        v[minV].know=true;
        cout<<minV<<endl;

        //更新它的鄰接頂點
        for(auto itr=v[minV].adjacentList.begin();itr!=v[minV].adjacentList.end();++itr)
        {
            if(!itr->first->know&&itr->first->dist>v[minV].dist+itr->second)
            {
                itr->first->dist=v[minV].dist+itr->second;
                itr->first->path=&v[minV];
            }
        }

    }





}




void Graph::printPath(Vertex* ver)
{
    if(ver->path!=nullptr)
    {
        printPath(ver->path);
        std::cout<<" to ";
    }
    std::cout<<"V"<<ver-&v[0];
}

main.cpp

#include "Graph.hpp"
#include <iostream>
#include <map>
using namespace std;
int main(int argc, const char * argv[]) {
    //圖由頂點和邊組成
    Graph g(7);//頂點數

    //輸入各個頂點的邊(鄰接頂點)
    g.setVertex(1, map<int,int>{{2,2},{4,1}});
    g.setVertex(2, map<int,int>{{4,3},{5,10}});
    g.setVertex(3, map<int,int>{{1,4},{6,5}});
    g.setVertex(4, map<int,int>{{3,2},{5,2},{6,8},{7,4}});
    g.setVertex(5, map<int,int>{{7,6}});
    g.setVertex(6, map<int,int>{});
    g.setVertex(7, map<int,int>{{6,1}});

    g.weighted(1);

    for(int i=1;i<=7;++i)
    {
        g.printPath(i);
        cout<<endl;
    }


    cout<<endl;
    return 0;
}

結果
1
4
2
3
5
7
6
shortest length from V1 to V1 is 0
V1

shortest length from V1 to V2 is 2
V1 to V2

shortest length from V1 to V3 is 3
V1 to V4 to V3

shortest length from V1 to V4 is 1
V1 to V4

shortest length from V1 to V5 is 3
V1 to V4 to V5

shortest length from V1 to V6 is 6
V1 to V4 to V7 to V6

shortest length from V1 to V7 is 5
V1 to V4 to V7

發佈了55 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章