Dijkstra算法那--赋权最短路径

来源:互联网 发布:节奏大师刷钻石软件 编辑:程序博客网 时间:2024/06/06 04:31

相对于无权最短路径,赋权最短路径多了一个成员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

原创粉丝点击