通信线路的敷设问题
问题描述
若要在下图中的13个城市之间建设通信网络,只需要敷设12条线路即可,边上的数字为两个城市之间建设线路的花费,单位:拾万元。如何以最低的经济代价建设这个通信网,是一个网的最小生成树的问题。
基本要求
⑴ 以邻接矩阵方式保存图的数据,并以邻接链表的形式输出图的数据;
⑵ 以边表方式保存图的数据,并以邻接矩阵方式的形式输出图的数据;
⑶ 用Prim算法求网的最小生成树,并以邻接链表的形式显示所求得的最小生成树,然后计算敷设相应的通信网的总造价;
⑷ 用Kruskal算法求网的最小生成树,并以邻接链表的形式显示所求得的最小生成树,然后计算敷设相应的通信网的总造价;
⑸ 整个应用设计成一个菜单,具有上述功能要求和退出系统的基本的功能;
main.c
#include <stdio.h>
#include <stdlib.h>
typedef int DataType;
typedef int VerT;
#define MaxSize 50
#define MAX_VERtEX_NUM 20
#define MaxVertices 20
#define MaxEdges 50
#define MaxWeight 10000
#define MaxQueueSize 50
#include "AdjMGraph.h"
#include "AdjMGraphCreate.h"//生成、存储邻接矩阵
#include "AdjLGraph.h"
#include"AdjLGraphCreate.h"//生成邻接表
#include "Prim.h"//prim算法
#include"Kruskal.h"//Kruskal算法
Edge *ListSort(Edge *head);
void putout(int a[], int n, RowColWeight mintree[], int e);
void frist(int a[], int n, RowColWeight rcw[], int e);
void two(int a[], int n, RowColWeight rcw[], int e);
void three(int a[], int n, RowColWeight rcw[], int e);
void four(int a[], int n, RowColWeight rcw[], int e);
void function_select(int a[], int n, RowColWeight rcw[], int e);
//链表排序函数,用于矩阵输出
Edge *ListSort(Edge *head){
//排序
Edge *p1, *p2, *pre;
p1 = head;
head = (Edge *)malloc(sizeof(Edge));
head->next = p1;
if (p1 == NULL){
return p1;
}
else{
p2 = p1->next; //保持p2是p1的后继结点,以保证不断链
p1->next = NULL;
p1 = p2;
while (p1){
p2 = p1->next; //保存p2的后继结点指针
pre = head;
while (pre->next != NULL && pre->next->dest < p1->dest)
{
pre = pre->next;
}
p1->next = pre->next;
pre->next = p1;
p1 = p2; //扫描剩下的结点
}
}
return (head->next);
}
//第一题:以邻接矩阵方式保存图的数据,并以邻接链表的形式输出图的数据
void frist(int a[], int n, RowColWeight rcw[], int e){
//邻接矩阵
int i, j;
AdjMWGraph g;
CreatGraph(&g, a, n, rcw, e);
printf("顶点集合为:");
for (i = 0; i < g.Vertices.size; i++)
printf("%d ", g.Vertices.list[i]);
printf("\n");
printf("以邻接矩阵方式保存图的数据:共%d个顶点 ,有%d条边\n\n\n", g.Vertices.size, g.numOfEdges/2);
printf("以邻接表输出为:\n");
for (i = 0; i < g.Vertices.size; i++)
{
printf("[%-2d|*]", g.Vertices.list[i]);
for (j = 0; j < g.Vertices.size; j++)
{
if (g.edge[i][j] == 10000 || i == j)
;
else{
printf("->");
printf("[%-2d|%-3d|*]", j + 1, g.edge[i][j]);
}
}
printf("\n");
}
}
//第二题:以边表方式保存图的数据,并以邻接矩阵方式的形式输出图的数据
void two(int a[], int n, RowColWeight rcw[], int e){
//邻接表
int i, j;
AdjLGraph g1;
LCreatGraph(&g1, a, n, rcw, e);
printf("以邻接矩阵方式保存图的数据:顶点个数:%d 边个数:%d\n\n\n", g1.numOfVerts, g1.numOfEdges / 2);
Edge *p;
printf("以邻接矩阵输出为:\n");
for (i = 0; i < g1.numOfVerts; i++)
{
if (i == 0)
printf("┎ ");
else if (i == g1.numOfVerts - 1)
printf("┖ ");
else
printf("┃ ");
g1.a[i].adj = ListSort(g1.a[i].adj);//对链表进行排序,以方便矩阵输出
p = g1.a[i].adj;
//矩阵输出
for (j = 0; j < g1.numOfVerts; j++){
if (p == NULL){
printf("∞ ");
}
else{
int m = p->dest;
//如果结点的dest值等于j,就输出权值
if (m == j){
printf("%-3d ", p->weight);
p = p->next;
}
else
printf("∞ ");
}
}
if (i == 0)
printf("┒");
else if (i == g1.numOfVerts - 1)
printf("┚");
else
printf("┃");
printf("\n");
}
AdjDestroy(&g1);
}
//第三题:用Prim算法求网的最小生成树,并以邻接链表的形式显示所求得的最小生成树,然后计算敷设相应的通信网的总造价;
void three(int a[], int n, RowColWeight rcw[], int e){
AdjMWGraph g;
int num = 0;
printf("Prim算法求网的最小生成树…………\n\n\n");
RowColWeight mintree[MaxEdges];
MinSpanTree closeVertex[13];
CreatGraph(&g, a, n, rcw, e);