#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; //边的数目
double **Distance; //Distance[i][j]表示第i个顶点到第j个顶点的最短路径长度,初始值为顶点i,j之间的权值
vector<int> **Path; //Path[i][j]表示第i个顶点到第j个顶点之间最短路径经过的顶点序列
int getposofvertex(vertexType& v); //求出顶点v在图中的位置
vertexType getvertex(int i); //求出顶点i代表的元素
double getWeight(int fromvertex,int tovertex); //获取顶点fromvertex到tovertex之间的权值
void Initializationwork(); //在求最短路径前的初始化工作
void UpdateDistanceAndPath(); //更新数组Distance和Path
public:
DirectedGraphofMatrix(int n,int m);
~DirectedGraphofMatrix();
void showGraph() const;
void PrintShortestPath(vertexType& one,vertexType& other); //打印顶点one到顶点other之间的最短路径
};
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);
}
this->Distance=new double* [this->vertexnum]; //为数组Distance,Path分配内存
if(!this->Distance) exit(0);
for(i=0;i<this->vertexnum;i++)
{
this->Distance[i]=new double[this->vertexnum];
if(!this->Distance[i]) exit(0);
}
this->Path=new vector<int>* [this->vertexnum];
if(!this->Path) exit(0);
for(i=0;i<this->vertexnum;i++)
{
this->Path[i]=new vector<int>[this->vertexnum];
if(!this->Path[i]) exit(0);
}
}
template<class vertexType>
DirectedGraphofMatrix<vertexType>::~DirectedGraphofMatrix()
{
int i;
for(i=0;i<this->vertexnum;i++)
{
delete []this->Distance[i];
delete []this->Path[i];
}
}
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() //在求最短路径前的初始化工作
{
int i,j;
for(i=0;i<this->vertexnum;i++)
{
for(j=0;j<this->vertexnum;j++) this->Distance[i][j]=this->getWeight(i,j);
}
}
template<class vertexType>
void DirectedGraphofMatrix<vertexType>::UpdateDistanceAndPath()
{
Initializationwork();
int i,j,k;
for(i=0;i<this->vertexnum;i++)
{
for(j=0;j<this->vertexnum;j++)
{
for(k=0;k<this->vertexnum;k++)
{
if(this->Distance[j][k]>this->Distance[j][i]+this->Distance[i][k])
// 将顶点i加入第j个顶点和第k个顶点的之间,如果Distance[j][k]>Distance[j][i]+Distance[i][k]
// 则说明第i个顶点是顶点i到顶点j的最短路径上的第i个顶点
{
this->Distance[j][k]=this->Distance[j][i]+this->Distance[i][k];
this->Path[j][k].push_back(i);
}
}
}
}
}
template<class vertexType>
void DirectedGraphofMatrix<vertexType>::PrintShortestPath(vertexType& one,vertexType& other)
{
int i,j;
i=this->getposofvertex(one);
if(i==-1) exit(0);
j=this->getposofvertex(other);
if(j==-1) exit(0);
this->UpdateDistanceAndPath();
double d=this->Distance[i][j];
vector<int>::const_iterator it;
cout<<" 顶点"<<one<<"到顶点"<<other<<"的最短路径长度是:"<<d<<endl;
cout<<"顶点"<<one<<"到顶点"<<other<<"的最短路径是:"<<one<<" ";
for(it=this->Path[i][j].begin();it!=this->Path[i][j].end();it++)
{
cout<<this->getvertex(*it)<<" ";
}
cout<<other<<endl;
}
void main()
{
int n,m;
cout<<"请输入顶点个数:";
cin>>n;
cout<<"请输入边的个数:";
cin>>m;
DirectedGraphofMatrix<char>g(n,m);
g.showGraph();
char one,other;
cout<<"请输入源点:";
cin>>one;
cout<<" 请输入目标点:";
cin>>other;
g.PrintShortestPath(one,other);
}
最短路径多源点Flod-Warshall算法
最新推荐文章于 2024-05-22 13:02:54 发布