最小生成树Prim算法学习

来源:互联网 发布:淘宝闲鱼怎么搜索 编辑:程序博客网 时间:2024/05/22 04:00
#include <iostream>using namespace std;#include <stdio.h>#include <stdlib.h>#define MAXSIZE 100typedef struct{    int vertex[MAXSIZE];    int edges[MAXSIZE][MAXSIZE];} MyGraph;void GrarhPrint(MyGraph*g,int n);void CreateMGraph(MyGraph*g,int e,int n);void Prim(MyGraph*g,int closevertex[],int n);void CreateMGraph(MyGraph*g,                  int e,//边数                  int n //顶点数                  ){    int i,j,k,m;    printf("Input data of vertex(0~n-1):\n");    for(i=0; i<n; i++)    {        g->vertex[i]=i; //把顶点0~n-1保存的数组中    }    //对顶点初始化,该开始都是没有通路    for(i=0; i<n; i++)    {        for(j=0; j<n; j++)        {            if(i==j)                g->edges[i][j]=0;            else                g->edges[i][j]=99;//99为不通        }    }    //输入通路,并确定边的权值    for(k=0; k<e; k++)    {        printf("Input edge of(i,j) and edge of size:");        scanf("%d%d%d",&i,&j,&m);        g->edges[i][j]=m;        g->edges[j][i]=m;    }    GrarhPrint(g,n);}//输出图的矩阵void GrarhPrint(MyGraph*g,int n){    int i=0;    int j=0;    for(i=0; i<n; i++)    {        for(j=0; j<n; j++)            if(g->edges[i][j]==99||i==j)                printf("∞\t");            else                printf("%d\t",g->edges[i][j]);//这里输入的是哪两个点之间有路径        printf("\n");    }}//构造图的最小生成树void Prim(MyGraph*g,          int closevertex[],//存储生成树已经确认的顶点          int n){    int lowcost[MAXSIZE];//用来存储顶点0到顶点n的权值(不是直接到达n)    int i,j,k,mincost;    for(i=1;i<n;i++)    {        lowcost[i]=g->edges[0][i];        closevertex[i]=0;    }    lowcost[0]=0;    closevertex[0]=0;    for(i=1;i<n;i++)    {        mincost=MAXSIZE;        j=1;        k=0;        while(j<n)        {            if(lowcost[j]!=0 && lowcost[j]<mincost)            {                mincost=lowcost[j];                k=j;            }            j++;        }        printf("Edge:(%d,%d),Wight:%d\n",k,closevertex[k],mincost);        lowcost[k]=0;        for(j=1;j<n;j++)        {            if(lowcost[j]!=0 && g->edges[k][j]<lowcost[j])            {                lowcost[j]=g->edges[k][j];                closevertex[j]=k;            }        }    }}int main(){    int closevertex[MAXSIZE];    MyGraph *g=(MyGraph*)malloc(sizeof(MyGraph));    CreateMGraph(g,10,6);    Prim(g,closevertex,6);    return 0;}

结果:
这里写图片描述
算法思想:假设G=(V,E)为一联通网,其中,V为网中所有顶点的集合,E为网中所有带权边的集合。设置两个新的集合U和T,其中,集合U用于存放G的最小生成树中的顶点,集合T存放G的最小生成数中的边。刚开始U、T为空,然后从集合V中选一顶点v1放入U中,接着在V-U中选一顶点,这个顶点到v1的距离最短,并将这个边加入到集合T中。
自己对Prime的理解:先创建一个邻接矩阵无向图,然后创建两个数组:
数组1:int closevertex[MAXSIZE];
数组2:int lowcost[MAXSIZE];
先把顶点0到每个顶点的距离存储到数组2中,然后从数组2中找到一个最小值min,并记录下标k,从K开始找每一条路径,若(k-n)的距离小于(0-n)的距离,更新数组2,把(0-n)的距离改成(k-n)的距离;并把下标n(1、2、3…..)与k借用数组1保存,如:a[n]=k;—意思是顶点n连接k,且k,j已保存到集合U中,不在集合V中。

原创粉丝点击