/*Prim算法:求一个无向连通图的最小生成树的算法,算法本质上利用图的割性质.图的割性质是指:将图的顶点人为地分成互不相交
的集合,这些集合可以通过交叉边连接起来,而连接这些集合的最小交叉边就是最小生成树的边,至于算法的证明在这里就不说明了自己可以上网查
图的一部分代码在其我的其它程序中有说明,就是图的ADT矩阵实现中有介绍,这里值得关注的代码是GRAPHmstV(graph* g)这个函数它是实现Prim算法的主体
*/
#include<stdio.h>
#include<stdlib.h>
static double maxWT=1000.00;
static int* fr , *st;
static double *wt;
#define p g->adj[v][w]
struct edge{int v,w ; double wt;};
edge EDGE(int v,int w , double wt){
edge e ; e.v = v , e.w = w , e.wt = wt;
return e;
}
double **MARTXint(int r, int c, double wt){
int i,j;
double **t=(double**)malloc(r*sizeof(double*));
for(i=0;i<r;i++)
t[i]=(double*)malloc(c*sizeof(double));
for(i=0;i<r;i++)
for(j=0;j<c;j++)
t[i][j]=wt;
return t;
}
struct graph{int V , E; double **adj; };
graph* graphinit(int V){
graph *g=(graph*)malloc(sizeof(graph));
g->V=V , g->E=0;
g->adj=MARTXint(V,V,maxWT);
return g;
}
void graphinsert(graph* g,edge e){
int v=e.v , w=e.w ;
if(g->adj[v][w]==maxWT) g->E++;
g->adj[v][w]=g->adj[w][v]=e.wt;
}
void graphshow(graph* g){
int i,j;
for(i=0;i<g->V;i++){
printf("%2d :", i);
for(j=0;j<g->V;j++)
if(g->adj[i][j]==maxWT) printf("* ");
else printf("%.2lf ",g->adj[i][j]);
printf("\n");
}
}
void GRAPHmstV(graph* g){
int v,w,min;
st=(int*)malloc(g->V*sizeof(int));
fr=(int*)malloc(g->V*sizeof(int)); //Prim算法的主体,本质是上是利用图的割性质的
wt=(double*)malloc((g->V+1)*sizeof(double)); //最后得出的结果是每个结点的父结点,通过这些结点就可以画出一棵最小生成树了
for(v=0;v<g->V;v++)
{st[v]=-1 , fr[v]= v , wt[v]=maxWT;}
st[0]=0 ; wt[g->V]=maxWT;
for(min=0;min!=g->V;){
v=min ; st[min]=fr[min]; //st[min]放的是树中每个结点的父结点比如st[7]=0 , 就表示7的父结点是0
for(w=0,min=g->V;w<g->V;w++)
if(st[w]==-1)
{
if(p<wt[w]){
wt[w]=p , fr[w]=v; //不断地更新边
}
if(wt[w]<wt[min]) min=w; //求出最短的交叉边
}
}
}
int main(){
int v,i,j;
double Wt;
scanf("%d",&v);
graph* g=graphinit(v);
while(scanf("%d%d%lf",&i,&j,&Wt) && i!=-1 && j!=-1)
graphinsert(g,EDGE(i,j,Wt));
printf("显示图中每条边的权值,‘*’表示没有这条边\n");
graphshow(g);
printf("最小生成树中每个结点的父结点\n");
GRAPHmstV(g);
printf(" ");
for(i=0;i<g->V;i++)
printf("%2d " , i);
printf("\n");
printf("st");
for(i=0;i<g->V;i++)
printf("%2d " ,st[i]);
printf("\n");
}
运行结果: