最小生成树(普里姆算法)

来源:互联网 发布:如何关闭阿里云盾 编辑:程序博客网 时间:2024/05/23 17:44
#include<stdio.h>#include<stdlib.h>#include<string.h>#include <limits.h>//#define INFINITY  INT_MAX//用整型最大值代替无穷大#define MAX_VERTEX_NUM 20//最大的顶点的个数#define MAX_NAME 3//定点字符串的最大长度+1typedef int VRType;typedef char VertexType[MAX_NAME];typedef char InfoType;//-------图的数组(邻接矩阵)存储表示-------typedef enum{DG,DN,UDG,UDN//有向图,有向网,无向图,无向网}GraphKind;typedef struct ArcCell{  VRType adj;// VRType是顶点关系类型,对无全图,用0或1,表示相邻否             //对带权图,则为权值类型  InfoType *info;//该弧的相关信息}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{  VertexType vexs[MAX_VERTEX_NUM];//定点向量  AdjMatrix arcs;//邻接矩阵  int vexnum,arcnum;//图的当前定点数和弧数  GraphKind kind;//图的种类标志}MGraph;//记录从顶点U到v-U的代价最小的边的辅助数组定义typedef struct{  VertexType adjvex;  VRType lowcost;}closedge[MAX_VERTEX_NUM];//查询某个顶点的位置函数int LocateVex(MGraph G,VertexType u)//此处u为顶点{  int i;  for(i=0;i<G.vexnum;i++)  {  if(strcmp(u,G.vexs[i])==0)  return i;  } if(i==G.vexnum) { printf("不存在该顶点!\n");     exit(1);  } return 0;}//创建有向网void CreatGraph(MGraph &G){  int i,j,k,adj;  char ch;  VertexType  v1,v2;  printf("请输入要创建的图的顶点的个数和边的个数(以空格隔开):");  scanf("%d%d",&G.vexnum,&G.arcnum);  ch=getchar();//吸收回车符  printf("请输入顶点的值:\n");  for(i=0;i<G.vexnum;i++)  {    scanf("%s",&G.vexs[i]);//输入顶点的值ch=getchar();  }  for(i=0;i<G.vexnum;i++)//先对整个邻接矩阵进行初始化  for(j=0;j<G.vexnum;j++)  {     G.arcs[i][j].adj=INFINITY;//权值为最大值 G.arcs[i][j].info=NULL;//顶点信息为空  }  printf("请输入图的弧的相关信息(v1,v2,adj即顶点1,顶点2,权值):\n"); for(k=0;k<G.arcnum;k++)//再根据输入的弧来更新邻接矩阵 {   scanf("%s%s%d",&v1,&v2,&adj);   ch=getchar();   i=LocateVex(G,v1);//找到顶点v1和v2的下表位置   j=LocateVex(G,v2);   G.arcs[i][j].adj=adj;//更新有关联的顶点的权值 } }//显示图的函数void display(MGraph G){   int i,j;   if(G.vexnum==0)   printf("该图是个空图!\n");   for(i=0;i<G.vexnum;i++)   {   for(j=0;j<G.vexnum;j++)   {     printf("%d  ",G.arcs[i][j].adj);   }   printf("\n");   }}//查询当前closedge.lowcost中最小的值int minmum(closedge &S,MGraph G){ int i=0,j,k,min;   while(!S[i].lowcost)//不为0 的情况下   i++;   k=i;   min=S[i].lowcost;   for(j=i+1;j<G.vexnum;j++)   {   if(S[j].lowcost>0)   {          if(min>S[j].lowcost)  {       k=j;   min=S[j].lowcost;  }     }   }   return k;}//用普里姆算法从第u个顶点除法构造网G的最小生成树T,输出T的各条边void MiniSpanTree_PRIM(MGraph G,VertexType u){  closedge min;  int k,j,i;  k=LocateVex(G,u);  for(j=0;j<G.vexnum;j++)//辅助数组初始化  {    if(j!=k) {  strcpy(min[j].adjvex,G.vexs[k]);  min[j].lowcost=G.arcs[k][j].adj;}  }  min[k].lowcost=0;//初始,U={u};  for(j=1;j<G.vexnum;j++)  {    k=minmum(min,G);//选择其余G.vexnum-1个顶点中与U集合中关联的权值最小的顶点printf("%s--%s\n",min[k].adjvex,G.vexs[k]);//输出生成树的边min[k].lowcost=0;//第k个顶点加入集合Ufor(i=0;i<G.vexnum;i++)//对辅助数组的重新更新{  if(G.arcs[k][i].adj<min[i].lowcost)  {    strcpy(min[i].adjvex,G.vexs[k]);    min[i].lowcost=G.arcs[k][i].adj;  }  }  }}int main(){   MGraph G;   CreatGraph(G);//创建图   display(G);//显示图   MiniSpanTree_PRIM(G,G.vexs[0]);//普里姆算法求最小生成树    return 0;}

原创粉丝点击