Minimum spanning tree problem

[ 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");
}



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325727867&siteId=291194637