数据结构——邻接矩阵表示的图的Dijkstra算法

  
    
#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)