Prim算法

来源:互联网 发布:mac 终端如何上传文件 编辑:程序博客网 时间:2024/06/06 21:33
思想:选定一个顶点,向外搜索与其他顶点相连的边的最小权值,将搜索到的顶点加入初始顶点集合,构成生成树,利用lowcost数组存储最小生成树到其他未加入生成树的点的距离,再次遍历,重复上述,直到所有点都被找到
偷了我们数据结构老师的一张图,以此来进行详解,我们以一个二维数组map来存储各点之间的距离,随意选择一个顶点出发遍历(最小生成树是为了求将图中所有顶点联通的最小距离,所以总路径长度即结果只有一个,所以节点是任选的),废话不多说,上代码:
#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#define MAX 1<<20#define M 1005#include<iostream>using namespace std;int lowcost[M];//当前生成树u的集合到其他各顶点的边最短的集合//lowcost初始为出发点到其他点的距离,不断更新为二叉树int vis[M];//标记节点是否进入生成树,1为进入,0为无int N;//顶点个数int e;//边的个数int map[M][M];//基础输入void prim(int N,int v)//v为出发点{    for(int i=0; i<N; i++)    {        lowcost[i]=map[v][i];//记录起点v距离其他点的距离        if(!lowcost[i])        {            lowcost[i]=MAX;        }        vis[i]=0;//初始化所有的点都没有进入二叉树    }    vis[v]=1;//很明显v进入二叉树,所以进行标记    int sum=0;//记录最短路长度,最短路数据存在lowlost数组里    int k;    int min;    int num;    for(int i=0; i<e; i++)    {        num=0;        min=MAX;//初始为最大值        for(int j=0; j<N; j++)        {            if(vis[j]==0&&lowcost[j]<min&&lowcost[j]>0)            {                min=lowcost[j];                k=j;                num++;            }        }//不断循环,知道发现与v相连的最小边,计入最短路        if(num)        {            sum+=min;            cout<<v<<"------"<<k<<"-------"<<min<<endl;        }        v=k;//此时将v更新为k,查找k的最近边        vis[k]=1;        //开始更新lowcost的数值,如果vis[j]==0;        //说明已经在此之前已经两个顶点已经联通,        //所以只遍历与出发点同属并查集但并未初始相连的点        for(int j=0; j<N; j++)        {            if(vis[j]==0&&map[v][j]<lowcost[j]&&map[v][j]>0)//此处v已经更新为新的节点,所以将其关联点距离与出发点距离各顶点做对比            {                lowcost[j]=map[v][j];            }        }    }    printf("%d\n",sum);}int main(){    int zz,ww;//zz为数量,ww为路数    int u,v,cost;    int p;    while(scanf("%d%d",&zz,&ww)!=EOF)    {        memset(lowcost,0,sizeof(lowcost));        memset(vis,0,sizeof(vis));        N=zz;        e=ww;        for(int i=0; i<ww; i++)        {            scanf("%d%d%d",&u,&v,&cost);            map[u][v]=cost;            map[v][u]=cost;        }        scanf("%d",&p);        prim(N,p);    }    return 0;}
结果如下:

原创粉丝点击