[ Problem description ]
To establish a communication network between n cities, only n-1 lines are required. How to construct this communication network with the lowest economic cost is the minimum spanning tree problem of a network.
[ Basic Requirements ]
( 1 ) Use the Turem or Kruskal algorithm to find the minimum spanning tree of the net;
( 2 ) Output each edge of the spanning tree and its weights in text form.
[implementation hints]
( 1) Once the communication line is established, it must be bidirectional, so the network that constructs the minimum spanning tree must be an undirected network;
( 2) Up to n(n-1)/2 lines can be set up between n cities; only n-1 lines are needed to establish a communication network between n cities. The problem is transformed into: how to choose n-1 routes among the possible routes, which can connect all the cities (vertices), and the total cost (sum of the weights of each edge) is the smallest.
#include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define INFINITY 99999 #define MAX_VERTEX_NUM 20 //Maximum number of vertices typedef int Status; typedef int InfoType; typedef char VertexType; //Arc node structure typedef struct ArcNode { int adjvex; //The position of the vertex pointed to by the arc struct ArcNode *nextArc; //Pointer to the next arc segment InfoType info; //Information about the arc } ArcNode; // vertex table structure typedef struct VNode { VertexType data; //The data type of the graph node ArcNode *firstarc; //The head pointer of the graph node, pointing to the first arc attached to the vertex }VNode,AdjList[MAX_VERTEX_NUM]; //Defines the vertex node and vertex table type //graph structure typedef struct { AdjList vertices; //The vertex table of the graph int vexnum,arcnum; //The number of vertices and arcs of the graph int kind; //The kind flag of the picture }ALGraph; //side information - used for minimum spanning tree algorithm to store side information typedef struct { int start node; int endnode; InfoType weight; }Edge; //For Prim minimum spanning tree algorithm typedef struct { VertexType adjvex; InfoType lowcost; } Closedge[MAX_VERTEX_NUM]; Closedge closedge; Status PrintElement(ALGraph G,int e) { // print the value of element e printf("%d ",G.vertices[e].data); // When practical, add the format string return OK; } //create graph Status CreateGraph(ALGraph &G); //destroy the graph Status DestroyGraph(ALGraph &G); //get vertex position int LocateVex(ALGraph G, VertexType u); //Get the first adjacent vertex of v int FirstAdjVex(ALGraph G,VertexType v); //Get the next adjacent vertex of v relative to w int NextAdjVex(ALGraph G,VertexType v,VertexType w); //add new vertex v Status InsertVex(ALGraph &G, VertexType v); // delete vertex v Status DeleteVex(ALGraph &G,VertexType v); //Add arc segment <v,w> Status InsertArc(ALGraph &G,VertexType v,VertexType w); //delete arc <v,w> Status DeleteArc(ALGraph &G,VertexType v,VertexType w); Status CreateUDN(ALGraph &G) { int v1,v2,w; int i,j,k; ArcNode *node=NULL; printf("Please enter the number of vertices and edges of graph G:\n"); scanf("%d%d",&G.vexnum,&G.arcnum); printf("Please input vertex (integer):\n"); for(i=0;i<G.vexnum;i++) { scanf("%d",&G.vertices[i].data); G.vertices[i].firstarc=NULL; } for(k=0;k<G.arcnum;k++) { printf("Please input an arc information<v1,v2,w>\n"); scanf("%d%d%d",&v1,&v2,&w); i=LocateVex(G,v1); j=LocateVex(G,v2); node=(ArcNode*)malloc(sizeof(ArcNode)); node->adjvex=j; node->info=w; //head insertion method node->nextArc=G.vertices[i].firstarc; G.vertices[i].firstarc=node; } return OK; }//CreateUDN-Undirected Network //destroy the graph Status DestroyGraph(ALGraph &G) { return OK; } //get vertex position int LocateVex(ALGraph G, VertexType u) { int i; for(i=0;i<G.vexnum;i++) { if(G.vertices[i].data==u) return i; } return -1; } //Get the first adjacent vertex of v int FirstAdjVex(ALGraph G,VertexType v) { ArcNode * p; int i; i=LocateVex(G,v); p=G.vertices[i].firstarc; if(p) return p->adjvex; return -1; } //Get the next adjacent vertex of v relative to w int NextAdjVex(ALGraph G,VertexType v,VertexType w) { ArcNode * p; int i; i=LocateVex(G,v); p=G.vertices[i].firstarc; while(p) { if(G.vertices[p->adjvex].data==w) { p=p->nextArc; if(p) return p->adjvex; else return -1; } p=p->nextArc; } return -1; } void PrintGraph(ALGraph G) { int i; ArcNode *p=NULL; printf("Vertex 1 (arc tail) Vertex 2 (arc head) the edge information:\n"); for(i=0;i<G.vexnum;i++) { printf("%d",G.vertices[i].data); p=G.vertices[i].firstarc; while(p) { printf("--%d %d ",(p->adjvex)+1,p->info); p=p->nextArc; } printf("\n"); } } int minimum(ALGraph G, Closedge elosedge) { int i,j; int min = INFINITY; for(i=0;i<G.vexnum;i++) { if(elosedge[i].lowcost>0&&min>elosedge[i].lowcost) { min=elosedge[i].lowcost; j=i; } } return j; } //Minimum spanning tree - Prim algorithm void MiniSpanTree_PRIM(ALGraph G, VertexType u) { // Algorithm 7.9 // Use Prim's algorithm to construct the minimum spanning tree T of network G from the u-th vertex, and output each edge of T. // Auxiliary array definition to record the least-cost edge from vertex set U to V-U: int i,j,k; ArcNode * p; k = LocateVex(G, u); for ( j=0; j<G.vexnum; ++j ) { // auxiliary array initialization if (j!=k) { closedge[j].adjvex=u; closedge[j].lowcost=INFINITY; } } // distance value on the right p=G.vertices[k].firstarc; while(p) { closedge[p->adjvex].lowcost=p->info; p = p->nextArc; } closedge[k].lowcost = 0; // Initial, U={u} for (i=1; i<G.vexnum; ++i) { // select the remaining G.vexnum-1 vertices k = minimum(G,closedge); // Find the next node of T: the kth vertex // closedge[k].lowcost = // MIN{ closedge[vi].lowcost | closedge[vi].lowcost>0, vi∈V-U } printf("(%d,%d,%d)\n",closedge[k].adjvex, G.vertices[k].data,closedge[k].lowcost); // Output spanning tree edges closedge[k].lowcost = 0; // the kth vertex is merged into the U set p=G.vertices[k].firstarc; while(p) { if (p->info>0&&p->info < closedge[p->adjvex].lowcost) { // reselect the smallest edge after the new vertex is merged into U // closedge[j] = { G.vexs[k], G.arcs[k][j].adj }; closedge[p->adjvex].adjvex=G.vertices[k].data; closedge[p->adjvex].lowcost=p->info; } p=p->nextArc; } } } // MiniSpanTree / / Determine whether there is an edge with endpoints i, j in the edge array Status HasEdge(Edge *edges,int n,int i,int j) { int k; for(k=0;k<n;k++) { if((edges[k].endnode==i&&edges[k].startnode==j)||(edges[k].startnode==i&&edges[k].endnode==j)) return TRUE; } return FALSE; }
Main function:
void main() { //create graph ALGraph G; int a,b; CreateUDN(G); printf("\nGraph created successfully!");PrintGraph(G); printf("Minimum spanning tree Prim algorithm:\n"); printf("Enter the vertex from which to construct the minimum spanning tree: "); scanf("%d",&b); MiniSpanTree_PRIM (G, b); printf("\n"); }