最小生成树之PRIM算法
问题:经典的就是最简单的。
用到两个数组:lowcost[] 和 closeset[],前者用来记录U集合和V集合的最小边,后者用来记录最小边的起始顶点。
代码:
#include <iostream> #include <cstdlib> using namespace std; #define MAXV 20 #define INFINITY 65535 typedef struct map { char vex[MAXV]; int arr[MAXV][MAXV]; int vexs,edges; }*mapNode; int locatePos(mapNode mn,char c) { int i; for(i=0;i<mn->vexs;i++) { if(mn->vex[i]==c) return i; //break; } return -1; } void createMap(mapNode &map) { char c,d; int p,q,w; cout<<"please input vexs and edges:"; cin>>map->vexs>>map->edges; cout<<"初始化图:"<<endl; for(int i=0;i<map->vexs;i++) { for(int j=0;j<map->vexs;j++) { map->arr[i][j]=INFINITY; } } cout<<"输入顶点字符:"<<endl; for(int k=0;k<map->vexs;k++) { cin>>map->vex[k]; } getchar(); for(int i=0;i<map->edges;i++) { cout<<"please input two char:"; cin>>c>>d; p=locatePos(map,c); q=locatePos(map,d); if(p==-1||q==-1) { cout<<"input error"<<endl; } else { cout<<"please input weight:"; cin>>w; map->arr[p][q]=w; map->arr[q][p]=w; } } } void showMap(mapNode map) { for(int i=0;i<map->vexs;i++) { for(int j=0;j<map->vexs;j++) { cout<<map->arr[i][j]<<" "; } cout<<endl; } } void MST_prim(mapNode map) { int w=0; //记录最小生成树的权值 int min; int lowcost[MAXV]; //记录U集合到V集合的最小边 int closeset[MAXV]; //记录U集合到V集合的起点 int f[MAXV]; int i,k,j; int temp; for(i=1;i<map->vexs;i++) { f[i]=1; //V集合 closeset[i]=0; } f[0]=0; //从第一个顶点开始 for(j=0;j<map->vexs;j++) lowcost[j]=map->arr[0][j]; for(k=1;k<=map->vexs-1;k++) //k个顶点至少k-1条边 { temp=0; min=INFINITY; for(i=1;i<map->vexs;i++) //找出U集合到V集合的最小边 { if((f[i]!=0)&&(lowcost[i]<min)) { min=lowcost[i]; temp=i; } } cout<<"("<<map->vex[closeset[temp]]<<","<<map->vex[temp]<<")"<<" "; w+=min; f[temp]=0; //加入到U集合 for(j=1;j<map->vexs;j++) //更新边集合,使U集合到V集合的边权值最小 { if((f[j]!=0)&&(map->arr[temp][j]<lowcost[j])) { lowcost[j]=map->arr[temp][j]; closeset[j]=temp; } } } cout<<"最小生成树权值为:"<<w<<endl; } int main() { mapNode map; map=(mapNode)malloc(sizeof(struct map)); cout<<"创建无向图:"<<endl; createMap(map); cout<<"输出无向图:"<<endl; showMap(map); cout<<endl; MST_prim(map); return 0; }
运行截图: