标签:style blog http strong 2014 os
考虑如下无向网:
邻接矩阵:
其最小生成树为:
下面将更新辅助数组,即挨个比较辅助数组与邻接表第k行的元素,如果邻接表的对应值小,那么就替换辅助数组值.
/********************************************** Prim算法求最小生成树 by Rowandjj 2014/7/1 ***********************************************/ #include<iostream> using namespace std; //--------------------------------------- #define MAX_VERTEX_NUM 20//边的最大值 #define INFINTY 65535//代表无穷大 typedef struct _ARC_ { int adj;//顶点关系类型 char *info;//弧信息 }Arc,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct _GRAPH_ { char vexs[MAX_VERTEX_NUM];//顶点向量 AdjMatrix arcs;//邻接矩阵 int vexnum,arcnum;//顶点数、弧数 }Graph; //---------------------------------------- typedef struct _ARRAY_//辅助数组 { char adjvex;//存储顶点 int lowcost;//存储权值 }minside[MAX_VERTEX_NUM]; //---------------------------------------- //图操作 int LocateVex(Graph G,char u); bool CreateAN(Graph *G);//构建无向网 void Display(Graph G);//打印无向网 //prim算法 void MiniSpanTree_PRIM(Graph G,char u);//用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边 int mininum(minside SZ,Graph G);//求closedge.lowcost的最小正值 //--------------------------------------- int LocateVex(Graph G,char u) { int i; for(i = 0; i < G.vexnum; i++) { if(G.vexs[i] == u) { return i; } } return -1; } bool CreateAN(Graph *G) { int i,j,k; int IncInfo; char va,vb;//顶点 int w;//权 char *info; char str[20]; cout<<"请输入无向网G的顶点数,边数,边是否含其它信息(是:1,否:0):\n"; cin>>G->vexnum; cin>>G->arcnum; cin>>IncInfo; cout<<"输入顶点的值:"; //初始化顶点 for(i = 0; i < G->vexnum; i++) { cin>>G->vexs[i]; } //初始化邻接矩阵 for(i = 0; i < G->vexnum; i++) { for(j = 0; j < G->vexnum; j++) { G->arcs[i][j].adj = INFINTY; G->arcs[i][j].info = NULL; } } cout<<"依次输入每条边的两个顶点及权值"<<endl; //初始化边 for(k = 0; k < G->arcnum; k++) { cin>>va; cin>>vb; cin>>w; i = LocateVex(*G,va); j = LocateVex(*G,vb); G->arcs[i][j].adj = w; G->arcs[j][i].adj = w; if(IncInfo)//弧信息 { cout<<"输入该边的相关信息:"; cin>>str; w = strlen(str)+1; if(w) { info = (char *)malloc(sizeof(char)*(w+1)); strcpy(info,str); G->arcs[i][j].info = G->arcs[j][i].info = info; } } } return true; } void Display(Graph G) { int i,j; cout<<"顶点:"; for(i = 0; i < G.vexnum; i++) { cout<<G.vexs[i]<<" "; } cout<<"\n邻接矩阵:\n"; for(i = 0; i < G.vexnum; i++) { for(j = 0; j < G.vexnum; j++) { cout<<G.arcs[i][j].adj<<" "; } cout<<endl; } cout<<endl; } //--------------------------------------------------------- int mininum(minside SZ,Graph G) { int i = 0,j; int min;//存储最小权值 int k;//存储权值最小的元素在数组中的位置 while(!SZ[i].lowcost)//忽略lowcost为0的元素 { i++; } min = SZ[i].lowcost; k = i; for(j = i+1; j< G.vexnum; j++) { if(SZ[j].lowcost > 0 && min > SZ[j].lowcost)//忽略lowcost为0的元素 { min = SZ[j].lowcost; k = j; } } return k; } void MiniSpanTree_PRIM(Graph G,char u) { minside closedge;//辅助数组 int i,j,k; k = LocateVex(G,u); if(k==-1) { return; } //初始化辅助数组 for(i = 0; i < G.vexnum; i++) { if(k != i) { closedge[i].adjvex = u;//复制顶点 closedge[i].lowcost = G.arcs[k][i].adj;//复制权 } } closedge[k].lowcost = 0;//初始,将第k顶点纳入U集 cout<<"最小代价生成树的各条边为:\n"; for(i = 1; i < G.vexnum; i++)//n个顶点的图的最小生成树有n-1条边 { k = mininum(closedge,G); cout<<closedge[k].adjvex<<"--->"<<G.vexs[k]<<endl;//输出生成树的边 closedge[k].lowcost = 0;//第k顶点并入U集 //更新辅助数组 for(j = 0; j < G.vexnum; j++) { if(closedge[j].lowcost > G.arcs[k][j].adj) { closedge[j].adjvex = G.vexs[k];//更新顶点名 closedge[j].lowcost = G.arcs[k][j].adj;//更新权 } } } cout<<endl; } //--------------------------------------------------------- int main() { Graph g; CreateAN(&g); Display(g); MiniSpanTree_PRIM(g,'a'); return 0; }测试:
标签:style blog http strong 2014 os
原文地址:http://blog.csdn.net/chdjj/article/details/36183845