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

来源:互联网 发布:mac系统使用视频教程 编辑:程序博客网 时间:2024/06/12 04:10


/*请把这个例子和Dijkstra算法一起看,会发现他们几乎一模一样有木有!*/#include<stdio.h>#include<iostream>#include<stdlib.h>using namespace std;#define inf 65535void prim(int c[][7],int n,int lowcost[],int closest[])//c是邻接矩阵,n为顶点个数,i从2到6,因为prim算法的初始顶点是任意的,索性就取顶点1作为初始顶点{   //lowcost[i]代表一轮V-S中的顶点i到S的所有点中最小的距离值,closest[i]表示每一轮每个顶点i到集合S中对应距离的最小值的那个顶点,即边i-closest[i]是针对i来说到集合S所有点的距离中最小的那个边 int s[7];//s判断顶点是否在S中,如果在就是1,不在就是0 for(int i=2;i<=n;i++)//初始化,除1之外的所有的点的lowcost[]都是直接与顶点1的距离 {lowcost[i]=c[1][i];closest[i]=1;//同时,closest[]初始化为1,毕竟此时S中只剩1号一个 s[i]=0;//现在顶点2到顶点6均未加入S阵营 }s[1]=1;//S中现在只剩1号一个 for(int i=1;i<=n-1;i++)//开始迭代,迭代次数为n-1 {int min=inf,j;//min和j用于记录每轮各个顶点(i从2到6)lowcost[i]的最小值,j用于记录顶点号 for(int k=2;k<=n;k++)//开始寻找最小值和最小值对应的顶点号了,这就是简单的擂台赛 if(!s[k]&&lowcost[k]<min){min=lowcost[k];j=k;}s[j]=1;//此时lowcost[i]的最小值对应的顶点号是j,那么就要把顶点j加入S集合中 for(int k=2;k<=n;k++)//顶点j加入了,此时需要修改现在的V-S阵营中每个顶点的lowcost[]和closest[]值,因为S发生了变化,因此相应的就需要改变 if(!s[k]&&c[j][k]<lowcost[k])//如果发现还有更小的,就更新lowcost[]和closest[]值,注意两个都要更新,不能只更新一个! {lowcost[k]=c[j][k];closest[k]=j;}}} void print(int lowcost[],int closest[],int n)//打印结果 {for(int i=2;i<=n;i++)cout<<i<<"--"<<closest[i]<<":"<<lowcost[i]<<endl;}int main(){int c[7][7]={  //因为我的顶点号是从1开始的,一共6个顶点,所以我申请了一个7×7的矩阵,下标为0的地方我设置成无穷大,不影响最后结果 {inf,inf,inf,inf,inf,inf,inf},{inf,inf,6,1,5,inf,inf},{inf,6,inf,5,inf,3,inf},{inf,1,5,inf,5,6,4},{inf,5,inf,5,inf,inf,2},{inf,inf,3,6,inf,inf,6},{inf,inf,inf,4,2,6,inf},};int lowcost[7],closest[7];prim(c,6,lowcost,closest);print(lowcost,closest,6);}


原创粉丝点击