#include <iostream>
#include <iomanip>
using namespace std;
#define MAX_VERTEX_NUM 10 //最大顶点个数
#define TRUE 1
#define FALSE 0
#define INFINITY 32767 /* 用整型最大值代替∞ */
typedef char VERTYPE;
typedef struct
{
VERTYPE vexs[MAX_VERTEX_NUM]; //顶点向量
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和弧数
}mgraph, * MGraph;
typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef int ShortPathTable[MAX_VERTEX_NUM];
void init_mgraph(MGraph &g) //初始化图
{
g=(MGraph)malloc(sizeof(mgraph));
g->vexnum=0;
g->arcnum=0;
for(int i=0;i<MAX_VERTEX_NUM;i++)
g->vexs[i]=0;
for(i=0;i<MAX_VERTEX_NUM;i++)
for(int j=0;j<MAX_VERTEX_NUM;j++)
g->arcs[i][j]=INFINITY;
}
void add_vexs(MGraph &g) //增加顶点
{
cout<<"请输入顶点的个数:"<<endl;
cin>>g->vexnum;
cout<<"请输入顶点的值"<<endl;
for(int i=0;i<g->vexnum;i++)
{
cin>>g->vexs[i];
}
}
void add_arcs(MGraph &g) //增加边
{
cout<<"请输入边的个数:"<<endl;
cin>>g->arcnum;
VERTYPE ch1,ch2;
int row,col,weight;
for(int i=0;i<g->arcnum;i++)
{
cin>>ch1>>ch2>>weight;
for(int j=0;j<g->vexnum;j++)
{
if(g->vexs[j]==ch1)
{
row=j;
}
if(g->vexs[j]==ch2)
{
col=j;
}
}
g->arcs[row][col]=weight; //有向带权图只需把1改为weight
}
}
void creat_mgraph(MGraph &g) //创建图
{
add_vexs(g); //增加顶点
add_arcs(g); //增加边
}
void print_mgraph(MGraph &g) //打印图
{
for(int i=0;i<g->vexnum;i++)
cout<<" "<<g->vexs[i]<<" ";
cout<<endl;
for(i=0;i<g->vexnum;i++)
{
cout<<g->vexs[i]<<" ";
for(int j=0;j<g->vexnum;j++)
{
cout<<setw(5)<<g->arcs[i][j]<<" ";
}
cout<<endl;
}
}
void ShortestPath_DIJ(MGraph &g, int v0, PathMatrix *P, ShortPathTable *D)
{
// 用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及带权长度D[v]。
// 若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点。
// final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径。
int v,w,i,j,min;
int final[MAX_VERTEX_NUM];
for(v=0; v<g->vexnum; ++v)
{
final[v] = FALSE;
(*D)[v] = g->arcs[v0][v];
for(w=0; w<g->vexnum; ++w)
(*P)[v][w] = FALSE; //设空路径
if((*D)[v] < INFINITY) //v0可以直接到达的点v
{
(*P)[v][v0] = TRUE; //v0是v0直接到达v的路径的始点
(*P)[v][v] = TRUE; //v是v0直接到达v的路径的终点
}
}//for
(*D)[v0] = 0;
final[v0] = TRUE; //初始化,v0顶点属于S集
//开始主循环,每次求得v0到某个v顶点的最短路径,并加入v到S集
for(i=1; i<g->vexnum; i++) //其余g.vexnum-1个顶点
{
min=INFINITY; //当前所知离v0顶点的最近距离
for(w=0; w<g->vexnum; w++)
{
if(!final[w] && (*D)[w]<min) //w顶点在V-S中
{
v=w;
min = (*D)[w]; //w顶点离v0顶点更近
}
}
final[v] = TRUE; //离v0顶点最近的v加入S集
for(w=0; w<g->vexnum; w++)
{ //更新当前最短路径及距离
if(!final[w] && ( min+g->arcs[v][w]<(*D)[w] ) ) //如果经过v顶点的路径比现在这条路径的长度短的话
{
// 修改D[w]和P[w],w∈V-S
(*D)[w] = min + g->arcs[v][w]; //修改当前路径长度
for(j=0;j<g->vexnum;++j)
(*P)[w][j]=(*P)[v][j]; //将经过v点的路径复制过来
(*P)[w][w]=TRUE; //最后的重点为TURE
}
}
}
}
int main()
{
MGraph G;
init_mgraph(G); //初始化图
creat_mgraph(G); //创建图
print_mgraph(G); //打印图
PathMatrix P;
ShortPathTable D;
//求某点到其余各点的最短路径
cout<<"输入源点的序号:"<<endl;
int v0;
cin>>v0;
ShortestPath_DIJ(G, v0, &P, &D);
cout<<"最短路径数组p[i][j]如下:"<<endl;
for(int i=0;i<G->vexnum;++i)
{
for(int j=0;j<G->vexnum;++j)
cout<<P[i][j]<<" ";
cout<<endl;
}
cout<<"源点到各顶点的最短路径长度为:"<<endl;
for(i=1;i<G->vexnum;++i)
cout<<G->vexs[0]<<" "<<G->vexs[i]<<" "<<D[i]<<endl;
return 0;
}
数据结构——邻接矩阵表示的图的Dijkstra算法
原文作者:Dijkstra算法
原文地址: https://blog.csdn.net/minyuanxiani/article/details/11000475
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/minyuanxiani/article/details/11000475
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。