要求
1、根据输入构造一个无向网络;
2、输出该无向网络对应的矩阵;
3、求出该无向网络的最小生成树并输出该最小生成树的所有的边。
代码
#include <stdio.h>
#include <stdlib.h>
#define INFINITY 100000 //最大值∞
#define MAX_VERTEX_NUM 20 //最大顶点个数
typedef struct
{
char vexs[MAX_VERTEX_NUM]; //顶点向量
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵
int vexnum, arcnum; //图的当前顶点和弧数
}MGraph;
typedef struct
{
int adjvex;
int endvex;
int lowcost;
} closedge[MAX_VERTEX_NUM];
void CreateUDN(MGraph& G); //创建无向网络
int LocateVex(MGraph G, char v); //结点的在顶点向量中的下标
void PrintUDN(MGraph G); //输出存储结构示意图
void MiniSpanTree_PRIM(MGraph G, closedge& minedge);//求最小生成树的算法
void PrintMinEdge(MGraph G, closedge minedge); //输出最小生成树的边
int main()
{
MGraph G;//定义一个图的变量
closedge minedge;
CreateUDN(G);
printf("该图的邻接矩阵存储示意图如下:\n");
PrintUDN(G);
printf("\n");
MiniSpanTree_PRIM(G, minedge);
printf("该图生成树的边如下:\n");
PrintMinEdge(G, minedge);
printf("\n");
return 0;
}
void CreateUDN(MGraph& 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();//吃掉前面scanf的\n
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] = G.arcs[j][i] = w; //边<v1, v2>的权值以及对称边<v2, v1>的权值为w
}
} //End_CreateUDN
int LocateVex(MGraph G,char v)
{
for (int i = 0; i < G.vexnum; ++i)
{
if (v == G.vexs[i])
return i;
}
}
void PrintUDN(MGraph G)//输出邻接矩阵
{
int i, j;
printf(" ");
for (i = 0; i < G.vexnum; i++)
{
printf("%c ", G.vexs[i]);//输出第一行的边元素
}
printf("\n");
for (i = 0; i < G.vexnum; ++i)
{
printf("%c ", G.vexs[i]);//输出第一列的边元素
for (j = 0; j < G.vexnum; ++j)
{
if (i == j)
{
printf("0 ");
}
else if(G.arcs[i][j] == INFINITY)
{
printf("∞ ");
}
else
{
printf("%d ", G.arcs[i][j]);
}
}
printf("\n");
}
}
void MiniSpanTree_PRIM(MGraph G, closedge& minedge)//用PRIM算法求出最小生成树
{
int i, j, k, z;
int temp;
int currentmin;
k = 0;
for (j = 1; j < G.vexnum; ++j)// 辅助数组初始化
{
minedge[j - 1].adjvex = k;
minedge[j - 1].endvex = j;
minedge[j - 1].lowcost = G.arcs[k][j];
}
for (i = 0; i < G.vexnum - 1; ++i)
{
currentmin = minedge[i].lowcost;
k = i;
for (j = i + 1; j < G.vexnum - 1; j++)//选择最小的边
{
if (minedge[j].lowcost < currentmin)
{
currentmin = minedge[j].lowcost;
k = j;
}
}
{//第k个元素与第i个进行交换
temp = minedge[i].adjvex;
minedge[i].adjvex = minedge[k].adjvex;
minedge[k].adjvex = temp;
temp = minedge[i].endvex;
minedge[i].endvex = minedge[k].endvex;
minedge[k].endvex = temp;
temp = minedge[i].lowcost;
minedge[i].lowcost = minedge[k].lowcost;
minedge[k].lowcost = temp;
}
for (j = i + 1; j < G.vexnum - 1; ++j)
{
z = minedge[i].endvex;//z为找到的新顶点
k = minedge[j].endvex;
if (k != z)
{
if (G.arcs[z][k] < minedge[j].lowcost)
{
minedge[j].adjvex = z;
minedge[j].lowcost = G.arcs[z][k];
}
}
}
}
} // MiniSpanTree
void PrintMinEdge(MGraph G, closedge minedge)//输出该最小生成树的所有的边
{
int i;
for (i = 0; i < G.vexnum-1; i++)
{
printf("%c%c %d\n", G.vexs[minedge[i].adjvex], G.vexs[minedge[i].endvex],minedge[i].lowcost);
}
}
**输入样例**
5 8
ABCDE
AB 8
AC 4
AE 3
BD 8
BE 6
CD 10
CE 13
DE 12
**输出样例**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201208230215245.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzUxMjI0NDky,size_16,color_FFFFFF,t_70)