您的位置:首页 > 其它

6)图[6]各顶点之间的最短路径

2015-12-03 16:16 375 查看
[b]有向图图中任何两个可到达的顶点之间最短路径以及相应的长度[/b]

[b]Dijkstra算法 和Floyd算法[/b]

#include "iostream"
#include "vector"
#include "stdlib.h"
using namespace std;

const int MaxNumVertex  = 20; //最大顶点数
const int infinity = 65535;//无穷大
typedef int elementtype;       //elementtype 为int 型
class graph{
public:
graph();
~graph();
elementtype insertvertex(elementtype v); //在图中增加一个顶点
elementtype insertedge(elementtype v,elementtype u,elementtype weight);//在图中增加一条从v顶点到u顶点的弧
elementtype firstadj(elementtype v);//求图g中顶点v的第一个邻接点
elementtype nextadj(elementtype v,elementtype m);//求图中顶点v的m邻接点之后的邻接点
elementtype degreeout(elementtype v);//求图中顶点v的出度数
elementtype FindDegreeout(elementtype oud[]);//各顶点的入度存放于出度数组中
elementtype Dijkstra(elementtype v0);//求解从v0到各顶点的最短路径
elementtype Floyd();//各顶点之间最短路径以及长度
elementtype create();//创建图
int  CurrentVertex;//当前顶点数

private:
elementtype vertex[MaxNumVertex];//顶点表
elementtype edge[MaxNumVertex][MaxNumVertex];//图中弧的类型

};

/*
*初始化
*/
graph::graph()
{
CurrentVertex = 0;
int i,j;
for (i=MaxNumVertex-1;i>=1;i--)
{
for (j=MaxNumVertex-1;j>=1;j--)
{
edge[i][j] = infinity;

}
}

}

/*
*在图中增加一个顶点
*/
elementtype graph::insertvertex(elementtype v)
{
//判断这个顶点是否已经存在
int i;
bool flags = true;
for(i=1; i<=CurrentVertex; i++)
{
if(vertex[i]==v)
{
flags = false;
break;
}
}

if(flags)
{
CurrentVertex++;
vertex[CurrentVertex] = v;
}else{
cout<<v<<"顶点已经存在!"<<endl;
}
return 0;
}

/*
*在图中增加一条从v顶点到u顶点的弧
*/
elementtype graph::insertedge(elementtype v,elementtype u,elementtype weight)
{
if(edge[v][u]!=infinity)
{
cout<<v<<"->"<<u<<"这条弧弧已经存在!"<<endl;
}else{
edge[v][u] = weight;
}
return 0;
}

/*
*求图中顶点v的第一个邻接点
*/
elementtype graph::firstadj(elementtype v)
{
int u,i;
bool flags = true;//用于判断是否存在邻接点
for(i=1;i<=CurrentVertex;i++)
{
if(edge[v][i]!=0){
u = i;
flags = false;
break;
}
}
if(flags) u = 0;//邻接点不存在
return u;
}

/*
*求图中顶点v的m邻接点以后的邻接点
*/
elementtype graph::nextadj(elementtype v,elementtype m)
{
int i,u;
bool flags = true;
for(i=m+1;i<=CurrentVertex;i++)
{
if(edge[v][i]!=0)
{
u = i;
flags = false;
break;
}
}
if(flags) u = 0;//邻接点不存在
return u;
}
/*
*求图中顶点v的出度数
*/
elementtype graph::degreeout(elementtype v)
{
int i,num = 0;
for (i=1;i<=CurrentVertex;i++)
{
if(edge[v][i]!=infinity)num++;
}
return num;
}

/*
*每个顶点的出度
*/
elementtype graph::FindDegreeout(elementtype outd[])
{
int i;
for(i=1;i<=CurrentVertex;i++)
{
outd[i] = degreeout(i);
}
return 0;
}

/*
*求解v0到各顶点的最短路径
*/
elementtype graph::Dijkstra(elementtype v0)
{
int i,j,k,w,v;
bool solved[20];
int dist[20];
vector<vector<int>>path(MaxNumVertex);//存储v0到各顶点的路径
for(i=1;i<=CurrentVertex;i++)
{
solved[i] = false;
}

solved[v0] = true;//将v0设置为已解顶点
for(i=1;i<=CurrentVertex;i++)
{
if(edge[v0][i]!=infinity)
{
dist[i] = edge[v0][i];
path[i].push_back(v0);
path[i].push_back(i);
}else{
dist[i] = infinity;
}
}

for(i=1;i<CurrentVertex;i++)
{
int min = infinity;
for(j=1;j<=CurrentVertex;j++)//在未解顶点中搜索最近的顶点v
{
if((solved[j]==false)&&(dist[j]<min))
{
min = dist[j];
v = j;
}
}

solved[v] = true;//所搜索到的当前最短的未解顶点为已解顶点
for(w=firstadj(v);w!=0;w=nextadj(v,w))//修改v的后继路径以及长度
{
if(dist[v]+edge[v][w]<dist[w])
{
dist[w] = dist[v]+edge[v][w];//修改w的dist值
path[w].clear();//清空w的path
//重新形成w的path
for(k=0;k<path[v].size();k++)
{
path[w].push_back(path[v][k]);
}
path[w].push_back(w);
}
}
}
for(i=1;i<=CurrentVertex;i++)
{
if((v0!=i)&&(dist[i]!=infinity))
{
cout<<"dist["<<v0<<"->"<<i<<"]:"<<dist[i]<<endl;
cout<<"path["<<v0<<"->"<<i<<"]:";
for(j=0;j<path[i].size();j++)
{
if(j<path[i].size()-1)cout<<path[i][j]<<",";
else cout<<path[i][j]<<endl;
}
}
}
cout<<endl;
return 0;
}

/*
*各顶点之间的最短路径以及长度
*/
elementtype graph::Floyd()
{
int i,j,k,m;
vector<vector<vector<int>>> path(MaxNumVertex,vector<vector<int>>(MaxNumVertex));//存储两个顶点之间的额路径
for(i=1;i<=CurrentVertex;i++)//初始化路径矩阵path
{
for(j=1;j<=CurrentVertex;j++)
{
if(edge[i][j]!=infinity)
{
path[i][j].push_back(i);
path[i][j].push_back(j);
}
}
}

for(k=1;k<=CurrentVertex;k++)//控制edge'k的求解
{
for(i=1;i<=CurrentVertex;i++)//求解edge'k[i][j]
{
for(j=1;j<=CurrentVertex;j++)
{
if(i!=j)
{
if(edge[i][k]+edge[k][j]<edge[i][j])
{
edge[i][j] = edge[i][k]+edge[k][j];
path[i][j].clear();
for(m=0;m<path[i][k].size();m++)
{
path[i][j].push_back(path[i][k][m]);
}
for(m=1;m<path[k][j].size();m++)
{
path[i][j].push_back(path[k][j][m]);
}
}
}
}
}
}
for(i=1;i<=CurrentVertex;i++)
{

for(j=1;j<=CurrentVertex;j++)
{
if((path[i][j].size()>0)&&(i!=j))
{
cout<<"dist["<<i<<"->"<<j<<"]:"<<edge[i][j]<<endl;
cout<<"path["<<i<<"->"<<j<<"]:";
for(k=0;k<path[i][j].size();k++)
{
if(k<path[i][j].size()-1)cout<<path[i][j][k]<<",";
else cout<<path[i][j][k]<<endl;
}
}

}
cout<<endl;
}
return 0;
}
/*
*创建图
*/
elementtype graph::create()
{
int i,numv,v,u,weight;
cout<<"please create graph"<<endl;
cout<<"input numvertex(顶点数):";
cin>>numv;
cout<<"input vertex(顶点):";
for(i=1;i<=numv;i++)
{
cin>>v;
insertvertex(v);
}
cout<<"input num(u,v,weight)(弧的数目):";
cin>>numv;
for(i=1;i<=numv;i++)
{
cout<<"u->v,weight:";
cin>>u>>v>>weight;
insertedge(u,v,weight);
}
cout<<"graph create finish!"<<endl<<endl;
return 0;
}
graph::~graph()
{
}

int main()
{
graph g;
g.create();
elementtype  outd[MaxNumVertex];
g.FindDegreeout(outd);
int i,selected;
cout<<"please select Algorithms:[1[Dijkstra Algorithm];2[Floyd Algorithms];3[Exit]]:"<<endl;
cout<<"continue[please input selected]:";
while(cin>>selected)
{
switch(selected)
{
case 1:
for(i=1;i<=g.CurrentVertex;i++)
{
if(outd[i]!=0)
{
g.Dijkstra(i);
cout<<endl;
}
}
cout<<"continue[please input selected]:";
break;
case 2:
g.Floyd();
cout<<"continue[please input selected]:";
break;
case 3:
exit(0);
break;
default:
exit(0);
break;
}
}
return 0;
}




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: