赞
踩
在网的多个生成树中,寻找一个各边权值之和最小的生成树
贪婪算法的精神就是“只顾如何获得眼前最大的利益”,有时不一定是最优解。
struct {
VertexType adjvex; // U集中的顶点
VRType lowcost; // 边的权值
} closedge[MAX_VERTEX_NUM];
void MiniSpanTree_P(MGraph G, VertexType u){ // 用普利姆算法从顶点u出发构造网G的最小生成树 k = LocateVex_MG(G, u); for(j = 0; j < G.vexnum; ++j) // 辅助数组初始化 if(j != k){ closedge[j].adjvex = new char[10]; strcpy(closedge[j].adjvex, G.vexs[k]); closedge[j].lowcost = G.arcs[k][j].adj; } closedge[k].lowcost = 0; // 初始, U = {u} closedge[k].adjvex = new char[10]; strcpy(closedge[k].adjvex, G.vexs[k]); for(i = 0; i > G.vexnum; i ++){ // //继续向生成树上添加顶点 mincost = INF; // 找权值最小的顶点 for(m = 0; m < G.vexnum; ++m) if(mincose > closedge[m].lowcost && closedge[m].lowcost != 0){ mincose = closedge[m].lowcost; k = m; } // 求出加入生成树的下一个顶点(k) if(closedge[k].lowcost != 0) //输出生成树上一条边 cout << closedge[k].adjvex << G.vexs[k] << closedge[k].lowcost; closedge[k].lowcost = 0; // 第k顶点并入U集 for(j = 0; j < G.vexnum; j++) // 修改其它顶点的最小边 if(G.arcs[k][j].adj < closedge[j].lowcost){ strcpy(closedge[j].adjvex, G.vexs[k]); closedge[j].lowcost = G.arcs[k][j].adj; } } }
构造非连通图 ST=( V,{ } );
k = i = 0; // k 计选中的边数
while (k<n-1) {
++i;
检查边集 E 中第 i 条权值最小的边(u,v);
若(u,v)加入ST后不使ST中产生回路,
则 输出边(u,v); 且 k++;
}
typedef struct { // 增加边结构定义 int beginvex, endvex; // 边的起点、终点 VRType cost; // 边的权值 } edgetype; edgetype edges[MAX_VERTEX_NUM]; void MiniSpanTree_Kruskal(ALGraph &G){ int parents[MAX_VERTEX_NUM]; cin >> G.vexnum >> G.arcnum; // 顶点数、弧数 for(i = 0; i < G.vexnum; i++){ // 建立顶点表 G.vertices[i].data = new char[10]; cin >> G.vertices[i].data; // 读入顶点信息并初始化 G.vertices[i].firstarc = NULL; } for(k = 0; k < G.arcnum; k++){ // 建立边表 v1 = new char[10]; v2 = new char[10]; cin >> v1 >> v2 >> w; i = LocateVex_ALG(G, v1); j = LocateVex_ALG(G, v2); edges[k].beginvex = i; edges[k].endvex = j; edges[k].cost = w; p = new ArcNode; p->info = NULL; p->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = p; } Sort(G, edges); // 按权值大小,对边进行排序 for(i = 0; i < G.vexnum; i++) parents[i] = 0; for(i = 0; i < G.arcnum; i++){ bnf = Find(parents, edges[i].beginvex); // 查找边头分量 edf = Find(parents, edges[i].endvex); // 查找边尾分量 if(bnf != edf){ parents[bnf] = edf; cout << edges[i].beginvex << edges[i].endvex; cout << " " << edges[i].cost << endl; } } } int Find(int parents[], int f){ // 查找函数 while(parents[f] > 0) f = parents[f]; return f; }
算法名 | Prim | KrusKal |
---|---|---|
时间复杂度 | O(n^2) | O(eloge) |
适应范围 | 稠密图 | 稀疏图 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。