Prim算法

来源:互联网 发布:iphone6屏幕解锁软件 编辑:程序博客网 时间:2024/06/16 03:03

Prim算法的思想:从图中任意取出一个顶点,把它当成一棵树,然后从与这颗树相接的边中选取一条最短(权值最小)的边,并将这条边及其多连接的顶点也并入这棵树中,此时得到了一棵有两个顶点的树,然后从与这棵树相接的边中选取一条最短的边,并将这条边及其所连顶点并入当前树中,得到一棵含有3个顶点的树,一次类推。。。

代码如下:

/*构造一张无向图*/#ifndef MGRAPH_H_#define MGRAPH_H_#define INF 9999#define maxSize 30typedef int VertexType;typedef struct {int edges[maxSize][maxSize];int n,e;VertexType vex[maxSize];}MGraph;void CreateMGraph( MGraph * G){int i,j,k,weight;int n1,n2;printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");scanf("%d,%d",&(G->n),&(G->e));//给顶点编号for(i=0;i<G->n;i++)G->vex[i]=i;for(i=0;i<G->n;i++)for(j=0;j<G->n;j++){                        G->edges[i][j]=INF;                        if(i==j)                            G->edges[i][j]=0;//邻接矩阵的对角线为0                        }        printf("请输入对应的边的结点号和边的权值(i,j,w)\n");for(k=0;k<G->e;k++){printf("第%d条边的结点号和权值:",k+1);scanf("%d,%d,%d",&i,&j,&weight);G->edges[i][j]=weight;G->edges[j][i]=weight;}}#endif

头文件MGraph.h结束


#include<stdio.h>#include"MGraph.h"typedef enum {NO,YES} Bool;Bool vset[maxSize];void Prim(MGraph const G,int const v0,int * sum){    int lowcost[maxSize],v;//lowcost保存的是当前生成树到顶点的最短边的权值    int i,j,k,min;    v=v0;    for(i=0;i<G.n;i++)    {        lowcost[i]=G.edges[v0][i];        vset[i]=NO;    }    vset[v0]=YES;    printf("%d",v0);    *sum=0;//sum 清零用来累计树的权值    for (i=0;i<G.n-1;i++)    {                        min=INF;        /*下面这个循环用于选出候选边中的最小者*/        for(j=0;j<G.n;j++)            if(vset[j]==NO && lowcost[j]<min)            {                min=lowcost[j];                k=j;            }        vset[k]=YES;        v=k;        *sum=(*sum)+min;        printf(" %d",k);        /*以刚并入的顶点V为媒介更新候选边*/        for(j=0;j<G.n;j++)            if(vset[j]==NO&&G.edges[v][j]<lowcost[j])                lowcost[j]=G.edges[v][j];    }}void main(void){    MGraph G;    int sum=0;    int i;    CreateMGraph(&G);    Prim(G,0,&sum);    printf("%d",sum);    }


0 0
原创粉丝点击