要求
1、根据输入构造一个有向网络;
2、输出该有向网络对应的矩阵;
3、求出该有向网络的最短路径。
代码
#include<stdio.h>
#define INFINITY 100000 //最大值 ∞
#define MVNum 100 //最大顶点数
int D[MVNum]; //用于记录最短路的长度
bool S[MVNum]; //标记顶点是否进入S集合
int Path[MVNum]; //用于记录最短路顶点的前驱
typedef struct {
char vexs[MVNum]; //顶点表
int arcs[MVNum][MVNum]; //邻接矩阵
int vexnum, arcnum; //图的当前点数和边数
}AMGraph;
int LocateVex(AMGraph G, char v) {
//确定点v在G中的位置
for (int i = 0; i < G.vexnum; ++i)
if (G.vexs[i] == v)
return i;
}//LocateVex
void CreateUDN(AMGraph& G) {
//采用邻接矩阵表示法,创建无向网G
//采用邻接矩阵表示法,创建无向网G
int i, j, k;
printf("请输入总顶点数,总边数,以空格隔开:\n");
scanf_s("%d %d", &G.vexnum, &G.arcnum);//输入总顶点数,总边数
getchar();
printf("依次输入点的名称,如A\n");
for (i = 0; i < G.vexnum; i++)
{
scanf_s("%c", &G.vexs[i]); //依次输入点的信息
}
for (i = 0; i < G.vexnum; i++) //初始化邻接矩阵,边的权值均置为极大值INFINITY
{
for (j = 0; j < G.vexnum; j++)
{
G.arcs[i][j] = INFINITY;
}
}
printf("请依次输入边依附的顶点及权值,如AB 5\n");
for (k = 0; k < G.arcnum; k++)//构造邻接矩阵
{
char v1, v2;
char ch;
int w;
getchar();
v1 = getchar();
v2 = getchar();
getchar();
getchar();
scanf_s("%d", &w);//输入一条边依附的顶点及权值
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
G.arcs[i][j] = w; //边<v1, v2>的权值为w
}//for
}//CreateUDN
void PrintUDN(AMGraph G)//输出邻接矩阵
{
int i, j;
printf(" ");
for (i = 0; i < G.vexnum; i++)
{
printf("%c\t ", G.vexs[i]);
}
printf("\n");
for (i = 0; i < G.vexnum; ++i)
{
printf("%c\t ", G.vexs[i]);
for (j = 0; j < G.vexnum; ++j)
{
if (i == j)
{
printf("0\t ");
}
else if (G.arcs[i][j] == INFINITY)
{
printf("∞\t ");
}
else
{
printf("%d\t ", G.arcs[i][j]);
}
}
printf("\n");
}
}
void ShortestPath_DIJ(AMGraph G, int v0) //用Dijkstra算法求有向网G的v0顶点到其余顶点的最短路径
{
int v, i, w, min; //n为G中顶点的个数
for (v = 0; v <G.vexnum; ++v)
{ //n个顶点依次初始化
S[v] = false; //S初始为空集
D[v] = G.arcs[v0][v]; //将v0到各个终点的最短路径长度初始化为弧上的权值
if (D[v] < INFINITY&&D[v]!=0)
{
Path[v] = v0;
} //如果v0和v之间有弧,则将v的前驱置为v0
else
{
Path[v] = -1; //如果v0和v之间无弧,则将v的前驱置为-1
}
}
S[v0] = true; //将v0加入S
D[v0] = 0; //源点到源点的距离为0
/*每次求得v0到某个顶点v的最短路径,将v加到S集―*/
for (i = 1; i < G.vexnum; i++)//对其余n-1个顶点,依次进行计算
{
min = INFINITY;
for (w = 0; w < G.vexnum; w++)
if (!S[w] && D[w]!=0&&D[w] < min) //选择一条当前的最短路径,终点为v
{
v = w;
min = D[w];
}//if
S[v] = true; //将v加入S
for (w = 0; w < G.vexnum; w++) //更新从v0出发到集合V?S上所有顶点的最短路径长度
if (!S[w] && (D[v] + G.arcs[v][w] < D[w]))
{
D[w] = D[v] + G.arcs[v][w]; //更新D[w]
Path[w] = v; //更改w的前驱为v
}
}
}
void DisplayPath(AMGraph G, int begin, int temp) //显示最短路
{
if (Path[temp] !=-1 )
{
DisplayPath(G, begin, Path[temp]);
printf("%c-->", G.vexs[Path[temp]]);
}
}//DisplayPath
void main()
{
AMGraph G;
int i, j;
CreateUDN(G);
PrintUDN(G);
ShortestPath_DIJ(G, 0);
printf("最短路径为:\n");
for (i = 1; i < G.vexnum; i++)
{
DisplayPath(G,0,i);
if (D[i] < INFINITY)
{
printf("%c ", G.vexs[i]);
printf("长度%d\n", D[i]);
}
else
{
printf("%c-->%c ", G.vexs[0], G.vexs[i]);
printf("无路径\n");
}
}
}
**输入示例**
6 8
ABCDEF
AC 10
AE 30
AF 100
BC 5
CD 50
DF 10
ED 20
EF 60
**输出**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201213223015553.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzUxMjI0NDky,size_16,color_FFFFFF,t_70)