相對於無權最短路徑,賦權最短路徑多了一個成員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