Prim最小生成树算法
2015-06-12 20:12
197 查看
Prim 算法
主要要解决问题
1、 尽可能选取权值小的边,但不能构成回路; 2、 选取n-1条恰当的边以连通n个顶点;
prim
MST性质:假设G=(V,E)是一个连通网,U是顶点V的一个非空子集。若(u,v)是一条具有最小权值的边,其中u∈U,v∈V-U,则必存在一棵包含边(u,v)的最小生成树。算法基本思想:
假设G=(V,E)是连通的,TE是G上最小生成树中边的集合。算法从U={u0}(u0∈V)、TE={}开始。重复执行下列操作:在所有u∈U,v∈V-U的边(u,v)∈E中找一条权值最小的边(u0,v0)并入集合TE中,同时v0并入U,直到V=U为止。此时,TE中必有n-1条边,T=(V,TE)为G的最小生成树。
Prim算法的核心:始终保持TE中的边集构成一棵生成树。
注意:prim算法适合稠密图,其时间复杂度为O(n^2),其时间复杂度与边得数目无关,而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图。
算法思想类似于迪杰斯特拉算法
以下代码来自于nocow:
const int N=500; unsigned long D ,Q ;//邻接阵表示距离,无边时此值为4294967295 bool cmp(int x,int y){return D[x]<D[y];} unsigned long Prim(void){ int i=N; list<int>L; for(memcpy(D,Q[0],sizeof(D)); --i; L.push_back(i));//以0号点为基准,L为还未进入最小生成树的点之集合 for(list<int>::iterator p;!L.empty();)//找到能见到的最短边,将新点从L中除去,然后以新点为基准,更新L中剩余点,直到L为空 for(p=min_element(L.begin(),L.end(),cmp),i=*p,L.erase(p),p=L.end(); L.end()!=++p; D[*p]<?=Q[i][*p]); return accumulate(1+D,N+D,0LU);//对D求和,即为最小生成树总长 }
相关文章推荐
- POJ 1094 Sorting It All Out
- POJ 2367 拓扑排序
- POJ 1258 Prim最小生成树
- ThumbnailUtils源码
- 贝叶斯网络
- 实验报告图遍历的演示
- 2015-06-12
- JS 拦截/捕捉 全局错误 全局Error onerror
- 在GridControl控件中使用SearchLookUpEdit构建数据快速输入
- Count Complete Tree Nodes 统计完全二叉树的节点数
- Maximal Square 最大的正方形
- DevExpress控件开发常用要点(项目总结版)
- ssh2. 相关配置文件
- 关于编程上的一些建议
- 赫夫曼编译码器实验报告
- mysql免安装版配置
- 链式运动框架
- UVA - 1347 Tour 双调欧几里得旅行商问题
- linux下如何安装配置redis及主从配置
- java最基本的四个数据类型大小和范围