求解最小生成树的算法 prim算法(附模板)
来源:互联网 发布:伺服控制系统编程 编辑:程序博客网 时间:2024/06/03 12:29
kruskal算法的链接 http://blog.csdn.net/winoros/article/details/21279967
接下来是prim算法。prim算法和kruskal算法同样是贪心,不过贪心的思路不同。
prim算法的步骤如下
1)标记任意一个点。
2)然后找一条边权最小的而且是一端被标记,另一端未被标记的边加进来。也就加入合法的最短边,然后将该边为被标记的顶点标记
3)这样进行到所有点都被标记即为结束。
算法的正确性个人感觉可以利用数学归纳法证明。证明如下
1)只有两个点标记时,明显该边边权必为最小。
2)假设有k个点被标记时,所加入的边了这k个点的最小生成树。
3)由于再加入的时候选取的是与现有生成树相连的边权最小的边,所以这时的k个边构成了这k+1个的最小生成树。
4)从而当所有点都被标记时所得边即构成了这张图的最小生成树。
具体的算法实现中,我们用一个bool数组marked[i]标记点i是否已计入最小生成树中,一个int数组dis[i]来表示未标记的点i加入最小生成树的最小权值(也就是点i到已标记的点最小的距离)
prim算法可以用堆优化,这里没有使用,只用邻接表实现。这里复杂度为O(N^2)(N为顶点的个数),相对于kruskal,prim算法更适合求稠密图,因为prim的复杂度与边的个数没有关系。
下面是代码
//made by winorosvector<pair<int, int> > v[MAX_N];bool marked[MAX_N];int dis[MAX_N];int prim(int n) { memset(marked, 0, sizeof(marked)); fill(dis, dis + n, INT_MAX);//这里顶点的标记总0开始 dis[0] = 0; int ans = 0; for(int i = 0; i <= n; i++) { int mark = -1; for(int j = 0; j <= n; j++) { if(!marked[j]) {//这个if是在找最小的dis[j] if(mark == -1) mark = j; else if(dis[j] < dis[mark]) mark = j; } } if(mark == -1) break; //如果已经无点可找(也就是所有的点都已进入最小生成树中),跳出循环 marked[mark] = true; ans += dis[mark]; for(int j = 0; j < v[mark].size(); j++) {//这个for是更新剩余点到最小生成树的距离 if(!marked[v[mark][j].first]) { int x = v[mark][j].first; dis[x] = min(dis[x],v[mark][j].second); } } } return ans;}
0 0
- 求解最小生成树的算法 prim算法(附模板)
- 求解最小生成树的算法 kruskal算法(附模板)
- 最小生成树(prim算法模板)
- 最小生成树-Prim算法(模板)
- Prim算法模板(最小生成树)
- 最小生成树(prim算法)模板
- 普里姆(Prim)算法求解最小生成树
- Prim算法求解最小生成树
- 求解最小生成树:Prim算法
- Prim算法求解最小生成树的Java实现
- 最小生成树Prim算法模板
- 最小生成树-prim算法模板
- hdu1233最小生成树 prim算法模板
- prim算法模板—最小生成树
- prim算法模板 (最小生成树)
- 【模板】最小生成树prim算法
- 最小生成树Prim算法模板
- 最小生成树Prim算法模板
- utf ucs16
- PHP简单工厂模式
- zoj3203 Light Bulb(三分)
- 字符串处理--表达式
- Android ExpandableListView 可展开的ListView
- 求解最小生成树的算法 prim算法(附模板)
- MD5加密C实现
- activity的使用(十二):启动录音
- Poj 2367 Genealogical tree(拓扑排序)
- 广搜--分糖果
- 个人博客的开始-2014/3/15
- 免安装的tomcat直接双击启动startup.bat闪退的问题
- C++返回数组指针
- linux挂载光驱