Dijkstra最短路径求解(不考虑权值为负的情况)

#include<iostream>
#include<vector>
#include<set>
#include<stack>
#include<stdlib.h>

using namespace std;

const int MaxNumber=1e10;
struct EdgeType //边的类型
{
 int fromvertex; //边的起点
 int tovertex;  //边的终点
 double weight; //边上的权值
};

template<class vertexType>
class DirectedGraphofMatrix //邻接矩阵存储的有向图
{
 private:
  vector<vertexType>vertex; //顶点向量
  int vertexnum; //顶点数目
  vector<EdgeType>edge; //边向量
  int edgenum; //边的数目
  set<int>redset; //红点集合,表示已经找到最短路径的点,初始状态只有一个起始顶点
  set<int>blueset; //蓝点集合,表示未找到最短路径的点,初始状态是图中除起始顶点外的所有顶点
  double *Distance; //Distance表示从起始顶点到各个目标顶点的权值
  int *path; //path[i]表示第i个顶点在最短路径中的父顶点

  int getposofvertex(vertexType& v); //求出顶点v在图中的位置
  vertexType getvertex(int i); //求出顶点i代表的元素
  double getWeight(int fromvertex,int tovertex); //获取顶点fromvertex到tovertex之间的权值
  void Initializationwork(vertexType& startvertex); //在求最短路径前的初始化工作
  int shortestdistanceofblueset(); //在蓝点集合中查找最短距离
  void adjustDistanceAndPath(int v); //依据顶点v调整Distance和path数组
  void printeachpath(int i); //打印从起始顶点到顶点i的一条最短路径
 public:
  DirectedGraphofMatrix(int n,int m);
  void showGraph() const;
  void shortestpath(vertexType& startvertex); //求起始顶点到其余顶点的最短路径
  void printshortestpath(); //打印从起始顶点到其余顶点的最短路径
};

bool checkInputFormat(istream& is) //检查输入格式是否正确
{
 if(!is.good())
 {
  cerr<<"输入格式错误!"<<endl;
  return false;
 }
 else return true;
}

template<class vertexType>
DirectedGraphofMatrix<vertexType>::DirectedGraphofMatrix(int n=0,int m=0):vertexnum(n),edgenum(m)
{
 int i;
 vertexType v;
 EdgeType e;
 for(i=0;i<n;i++)
 {
  cout<<"请输入第"<<i<<"个顶点:";
  cin>>v;
  if(!checkInputFormat(cin)) return;
  else this->vertex.push_back(v);
 }
 for(i=0;i<m;i++)
 {
  cout<<"请输入第"<<i<<"条边的起点:";
  cin>>e.fromvertex;
  cout<<"请输入第"<<i<<"条边的终点:";
  cin>>e.tovertex;
  cout<<"请输入第"<<i<<"条边的权值:";
  cin>>e.weight;
  this->edge.push_back(e);
 }
 Distance=new double[vertexnum];
 path=new int[vertexnum];
 if(!Distance || !path) exit(0);
}

template<class vertexType>
void DirectedGraphofMatrix<vertexType>::showGraph() const
{
 int i;
 for(i=0;i<this->vertexnum;i++)
 {
  cout<<"第"<<i<<"个顶点是:"<<this->vertex[i]<<endl;
 }
 for(i=0;i<this->edgenum;i++)
 {
  cout<<"第"<<i<<"条边的起点是:"<<this->edge[i].fromvertex<<endl;
  cout<<"第"<<i<<"条边的终点是:"<<this->edge[i].tovertex<<endl;
  cout<<"第"<<i<<"条边的权值是:"<<this->edge[i].weight<<endl;
 }
}

template<class vertexType>
int DirectedGraphofMatrix<vertexType>::getposofvertex(vertexType& v)
{
 int i;
 for(i=0;i<this->vertexnum;i++)
 {
  if(v==this->vertex[i]) return i;
 }
 return -1;
}

template<class vertexType>
vertexType DirectedGraphofMatrix<vertexType>::getvertex(int i)
{
 int j;
 for(j=0;j<vertexnum;j++)
 {
  if(i==j) return this->vertex[i];
 }
}

template<class vertexType>
double DirectedGraphofMatrix<vertexType>::getWeight(int fromvertex,int tovertex)
{
 int i;
 for(i=0;i<edgenum;i++)
 {
  if(this->edge[i].fromvertex==fromvertex && this->edge[i].tovertex==tovertex)
  {
   return this->edge[i].weight;
  }
 }
 return MaxNumber;
}

template<class vertexType>
void DirectedGraphofMatrix<vertexType>::Initializationwork(vertexType& startvertex) //在求最短路径前的初始化工作
{
 int start;
 if((start=this->getposofvertex(startvertex))==-1)
 {
  cerr<<"图中无此顶点!"<<endl;
  return;
 }
 this->redset.insert(start); //插入起始顶点
 int i;
 this->Distance[start]=0;
 this->path[start]=-1;
 for(i=0;i<vertexnum;i++)
 {
  if(this->vertex[i]!=startvertex)
  {
   this->blueset.insert(i); //在蓝点集合中插入其余顶点序号
   this->Distance[i]=this->getWeight(start,i); //将顶点start到顶点i的权值放入Distance[i]中
   if(this->Distance[i]!=MaxNumber) //顶点start到顶点i直接相连
   {
    this->path[i]=start;
   }
   else this->path[i]=-1;
  }
 }
}

template<class vertexType>
int DirectedGraphofMatrix<vertexType>::shortestdistanceofblueset()
{
 int i,pos;
 pos=-1;
 double mindistance=MaxNumber;
 for(i=0;i<this->vertexnum;i++)
 {
  if(this->blueset.count(i))
  {
   if(this->Distance[i]<mindistance)
   {
    pos=i;
    mindistance=this->Distance[i];
   }
  }
 }
 return pos;
}

template<class vertexType>
void DirectedGraphofMatrix<vertexType>::adjustDistanceAndPath(int v)
{
 int i;
 double d;
 for(i=0;i<this->vertexnum;i++)
 {
  if(this->blueset.count(i))
  {
   d=this->Distance[v]+this->getWeight(v,i);
   if(d<this->Distance[i])
   {
    this->path[i]=v;
    this->Distance[i]=d;
   }
  }
 }
}

template<class vertexType>
void DirectedGraphofMatrix<vertexType>::shortestpath(vertexType& startvertex)
{
 this->Initializationwork(startvertex);
 int i;
 while(!this->blueset.empty())
 {
  i=this->shortestdistanceofblueset(); //从蓝点集合中选择一个与起始顶点距离最近的顶点i
  this->blueset.erase(i); //将顶点i从蓝点集合中删除
  this->redset.insert(i); //将顶点i加入到红点集合
  this->adjustDistanceAndPath(i); //依据顶点i调整数组distance和path
 }

 for(i=0;i<vertexnum;i++)
 {
  cout<<this->Distance[i]<<" ";
 }
 cout<<endl;
 for(i=0;i<vertexnum;i++)
 {
  cout<<this->path[i]<<" ";
 }
 cout<<endl;
}

template<class vertexType>
void DirectedGraphofMatrix<vertexType>::printeachpath(int i)
{
 int parent; //parent是当前顶点的父顶点
 double d=this->Distance[i]; //d是起始顶点到顶点i的最短路径长度
 stack<int>s; //栈s用于保存最短路径上的顶点
 cout<<"起始顶点到顶点"<<this->getvertex(i)<<"的最短路径是:";
 while((parent=this->path[i])!=-1) //顶点i有父顶点
 {
  s.push(parent);
  i=parent;
 }
 while(!s.empty())
 {
  cout<<this->getvertex(s.top())<<" ";
  s.pop();
 }
 cout<<d<<endl;
}

template<class vertexType>
void DirectedGraphofMatrix<vertexType>::printshortestpath()
{
 int i;
 for(i=0;i<vertexnum;i++)
 {
  this->printeachpath(i);
 }
}

void main()
{
 int n,m;
 cout<<"请输入顶点个数:";
 cin>>n;
 cout<<"请输入边的个数:";
 cin>>m;
 DirectedGraphofMatrix<char>g(n,m);
 g.showGraph();
 char startvertex;
 cout<<"请输入起始顶点:";
 cin>>startvertex;
 g.shortestpath(startvertex);
 g.printshortestpath();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值