Prime算法
2015-08-12 22:31
316 查看
普利姆(Prime)算法(只与顶点相关)
算法描述:
普利姆算法求最小生成树时候,和边数无关,只和定点的数量相关,所以适合求稠密网的最小生成树,时间复杂度为O(n*n)。
算法过程:
1.将一个图的顶点分为两部分,一部分是最小生成树中的结点(A集合),另一部分是未处理的结点(B集合)。
2.首先选择一个结点,将这个结点加入A中,然后,对集合A中的顶点遍历,找出A中顶点关联的边权值最小的那个(设为v),将此顶点从B中删除,加入集合A中。
3.递归重复步骤2,直到B集合中的结点为空,结束此过程。
4.A集合中的结点就是由Prime算法得到的最小生成树的结点,依照步骤2的结点连接这些顶点,得到的就是这个图的最小生成树。
算法实现具体过程:
1.将第一个点放入最小生成树的集合中(标记visit[i]=1意思就是最小生成树集合)。
2.从第二个点开始,初始化lowcost[i]为跟1点相连(仅仅相连)的边的权值(lowcost[i]不是这个点的最小权值!在以后会逐步更新)。
3.找最小权值的边。
从第二点开始遍历,如果不是最小生成树的集合的点,则找出从2到n的最小权值(lowcost[j])。
4.将找出来的最小权值的边的顶点加入最小生成树的集合中(标记visit[i] = 1),权值想加。
5.更新lowcost[j]集合。
假设第一次:lowcost[2]代表与1相连的点的权值,现在加入了k点。则比较k点与2点的边map[k][2]和lowcost[2]的大小,若lowcost[2]大,则lowcost[2] = map[k][2]。(关键步骤:实质就是每在最小生成树集合中加入一个点就需要把这个点与集合外的点比较,不断的寻找两个集合之间最小的边)
6.循环上述步骤,指导将全部顶点加入到最小生成树集合为止。
代码如下:
算法描述:
普利姆算法求最小生成树时候,和边数无关,只和定点的数量相关,所以适合求稠密网的最小生成树,时间复杂度为O(n*n)。
算法过程:
1.将一个图的顶点分为两部分,一部分是最小生成树中的结点(A集合),另一部分是未处理的结点(B集合)。
2.首先选择一个结点,将这个结点加入A中,然后,对集合A中的顶点遍历,找出A中顶点关联的边权值最小的那个(设为v),将此顶点从B中删除,加入集合A中。
3.递归重复步骤2,直到B集合中的结点为空,结束此过程。
4.A集合中的结点就是由Prime算法得到的最小生成树的结点,依照步骤2的结点连接这些顶点,得到的就是这个图的最小生成树。
算法实现具体过程:
1.将第一个点放入最小生成树的集合中(标记visit[i]=1意思就是最小生成树集合)。
2.从第二个点开始,初始化lowcost[i]为跟1点相连(仅仅相连)的边的权值(lowcost[i]不是这个点的最小权值!在以后会逐步更新)。
3.找最小权值的边。
从第二点开始遍历,如果不是最小生成树的集合的点,则找出从2到n的最小权值(lowcost[j])。
4.将找出来的最小权值的边的顶点加入最小生成树的集合中(标记visit[i] = 1),权值想加。
5.更新lowcost[j]集合。
假设第一次:lowcost[2]代表与1相连的点的权值,现在加入了k点。则比较k点与2点的边map[k][2]和lowcost[2]的大小,若lowcost[2]大,则lowcost[2] = map[k][2]。(关键步骤:实质就是每在最小生成树集合中加入一个点就需要把这个点与集合外的点比较,不断的寻找两个集合之间最小的边)
6.循环上述步骤,指导将全部顶点加入到最小生成树集合为止。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define MAXN 110 int map[MAXN][MAXN], lowcost[MAXN]; bool visit[MAXN]; int nodenum, sum; void prim() { int temp, k; sum = 0; memset(visit, false, sizeof(visit)); //初始化visit visit[1] = true; for(int i = 1; i <= nodenum; ++i) //初始化lowcost[i] lowcost[i] = map[1][i]; for(int i = 1; i <= nodenum; ++i)//找生成树集合点集相连最小权值的边 { temp = INF; for(int j = 1; j <= nodenum; ++j) if(!visit[j] && temp > lowcost[j]) temp = lowcost[k = j]; if(temp == INF) break; visit[k] = true; //加入最小生成树集合 sum += temp;//记录权值之和 for(int j = 1; j <= nodenum; ++j) //更新lowcost数组 if(!visit[j] && lowcost[j] > map[k][j]) lowcost[j] = map[k][j]; } } int main() { int a, b, cost, edgenum; while(scanf("%d", &nodenum) && nodenum) { memset(map, INF, sizeof(map)); edgenum = nodenum * (nodenum - 1) / 2; for(int i = 1; i <= edgenum; ++i) //输入边的信息 { scanf("%d%d%d", &a, &b, &cost); if(cost < map[a][b]) map[a][b] = map[b][a] = cost; } prim(); printf("%d\n", sum); //最小生成树权值之和 } return 0; }
相关文章推荐
- hihocoder Beautiful String
- Exception in thread "main" java.lang.NoClassDefFoundError: Demo (wrong name: com/zhangyun/Demo)解决办法
- 函数调用
- hdu 5335 Walk Out(暴力)
- UIPageControl
- python网络编程(2)
- HDU 3336 Count the string (KMP next数组运用——统计前缀出现次数)
- 谷歌被墙,如何给谷歌浏览器添加迅雷下载插件
- Path Patterns 和 Patterns with Placeholders
- extern 关键字的使用 《程序员的自我修养》·笔记
- linux 做 wifi 热点(俗称AP)
- UI 06 _ 7种手势
- linux/Ubantu 解压缩jdk失败的解决方案
- 集合的规则与使用简介
- file上传按钮替换以及解决IE浏览器隐藏file按钮不能上传文件问题
- HDU 1019
- [Vijos]P1788 第k大
- 《机器学习系统设计》之应用scikit-learn做文本分类(上)
- Codeforces Round #200 (Div. 2) C. Rational Resistance(脑洞思维)
- STL容器相关内容