权重最小生成树的思想与Kruskal算法
本文有更新,请移步我的个人博客:https://blog.andyqiao.top/article/9/
晚上做携程的笔试题,附加题考到了权重最小生成树。OMG,就在开考之前,我还又看过一遍这内容,可因为时间太紧,也从来没有写过代码,就GG了。又吃了眼高手低的亏。这不,就好好总结一下,亡羊补牢。
权重最小生成树问题是指在一棵无向全连接图中找到一个无环子集T,既能将所有的结点连接起来,又具有最小的权重和。
解决问题的核心是每次找到一条安全边加入到边集合A中,使得A仍然是某棵最小生成树的子集。
Kruskal找到安全边的方法是:在所有连接森林中两棵不同树的边里面,找到权重最小的边(u,v),(1)如果u和v位于不同的子树,则该边就是一个安全边,将u和v位于的子树合并起来;(2)如果u和v位于相同子树,则该边不是一个安全边,如果将两棵子树连接起来,就会形成一个环。
我用详细注释的代码说明问题:
//合并节点a和b所属的两棵子树
void Union(int a, int b, int V,vector<int>& root)
{
int root_a = root[a],root_b = root[b];
//把b所在树的所有顶点都移植过去给a... for (int i = ; i < V; i++)
if (root[i] == root_b)
root[i] = root_a;
}
//sort的比较函数
bool compare(const CEdge &a, const CEdge &b)
{
return a.weight < b.weight;
}
//Kruskal最小生成树算法
void Kruskal(int V, int E, vector<CEdge> &e,vector<int>& root)
{
//以权重为参考值,排序所有边
sort(e.begin(), e.end(), compare);
int cnt = ;
for (int i = ; i < E; i++)
if (root[e[i].u]!=root[e[i].v]) //如果e[i].u和e[i].v不属于同一棵子树
{
cout << e[i].u << "---" << e[i].v << " "<<e[i].weight<<endl;//加入该边
Union(e[i].u, e[i].v, V,root); //合并两棵子树 //易知最小生成树拥有V-1条边
//如果已经组成最小生成树,就退出循环
++cnt;
if (cnt >= V - )
break;
}
}
int main()
{
int V = ;
vector<CEdge> edges;
edges.push_back({ , , });
edges.push_back({ , , });
edges.push_back({ , , });
edges.push_back({ , , });
edges.push_back({ , , });
edges.push_back({ , , }); //使用一个vector来表示各个子树(即集合A),
//root[i]=j,表示节点i与节点j位于同一子树上,并且所有位于此树的节点k,都有root[k]=j;
//初始化root[i]=i,表示每棵子树只是一个节点
vector<int> root(V, );
for (int i = ; i < V; ++i)
root[i] = i; //执行算法
Kruskal(V, edges.size(), edges, root); while ();
return ;
}
程序输出:
0---1 1
0---2 2
2---3 2
权重最小生成树的思想与Kruskal算法的更多相关文章
- 最小生成树---Prim算法和Kruskal算法
Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...
- 转载:最小生成树-Prim算法和Kruskal算法
本文摘自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html 最小生成树-Prim算法和Kruskal算法 Prim算 ...
- 最小生成树Prim算法和Kruskal算法(转)
(转自这位大佬的博客 http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html ) Prim算法 1.概览 普里姆算法(Pr ...
- 【数据结构】 最小生成树(二)——kruskal算法
上一期说完了什么是最小生成树,这一期咱们来介绍求最小生成树的算法:kruskal算法,适用于稀疏图,也就是同样个数的节点,边越少就越快,到了数据结构与算法这个阶段了,做题靠的就是速度快,时间复杂度小. ...
- 最小生成树Prim算法和Kruskal算法
Prim算法(使用visited数组实现) Prim算法求最小生成树的时候和边数无关,和顶点树有关,所以适合求解稠密网的最小生成树. Prim算法的步骤包括: 1. 将一个图分为两部分,一部分归为点集 ...
- MST最小生成树及克鲁斯卡尔(Kruskal)算法
最小生成树MST,英文名如何拼写已忘,应该是min spaning tree吧.假设一个无向连通图有n个节点,那么它的生成树就是包括这n个节点的无环连通图,无环即形成树.最小生成树是对边上权重的考虑, ...
- 最小生成树——Prim算法和Kruskal算法
洛谷P3366 最小生成树板子题 这篇博客介绍两个算法:Prim算法和Kruskal算法,两个算法各有优劣 一般来说当图比较稀疏的时候,Kruskal算法比较快 而当图很密集,Prim算法就大显身手了 ...
- hdu1233 最小生成树Prim算法和Kruskal算法
Prim算法 时间复杂度:O(\(N^2\),N为结点数) 说明:先任意找一个点标记,然后每次找一条最短的两端分别为标记和未标记的边加进来,再把未标记的点标记上.即每次加入一条合法的最短的边,每次扩展 ...
- 【2018寒假集训Day 8】【最小生成树】Prim和Kruskal算法模板
Luogu最小生成树模板题 Prim 原理与dijkstra几乎相同,每次找最优的点,用这个点去松弛未连接的点,也就是用这个点去与未连接的点连接. #include<cstdio> #in ...
随机推荐
- Java面向对象练习
1.定义长方形类,含: 属性:宽.高(整型): 方法:求周长.面积: 构造方法3个:(1)无参——宽.高默认值为1:(2)1个参数——宽.高均为参数值:(3)2个参数——宽.高各为参数值. 要求:进行 ...
- 如何搭建Percona XtraDB Cluster集群
一.环境准备 主机IP 主机名 操作系统版本 PXC 192.168.244.146 node1 ...
- nodejs与javascript中的aes加密
简介 1.aes加密简单来说,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用.高级加密标准已然成为对称密钥加 ...
- Oracle OCP 1Z0-053 Exam Topics
根据OU官方发布的考试大纲,OCP 1Z0-053考点如下: 1. Database Architecture and ASM Describe Automatic Storage Managemen ...
- iOS-掌握了时间就掌握了一切!
Demo下载地址 一. NSDate相关知识 1.获取当前时间 [NSDate date]; 注意: 获取的当前时间是世界时间:比我们用的时间慢8个小时. 2.世界时间转化为本地时间 - (void) ...
- AngularJs之Scope作用域
前言: 上篇博文AngularJs之directive中说了Scope作用域是个大坑,所以拿出来作为重点总结! 什么是scope AngularJS 中,作用域是一个指向应用模型的对象,它是表达式的执 ...
- jQuery-1.9.1源码分析系列(一)整体架构续
这一节主要是jQuery中最基础的几个东东 2. jQuery的几个基础属性和函数 a. jQuery.noConflict函数详解 在jQuery初始化的时候保存了外部的$和jQuery _j ...
- linux中的通配符与正则表达式
在linux中,有通配符及正则表达式,那么什么是通配符和正则表达式,什么时候用? 通配符 它是由shell解析,并且一般用于匹配文件名,实际上就是shell解释器去解析的特殊符号,linux系统通 ...
- 我的runtime学习笔记
0.简介: OC方法不同于C语言函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用. 至于其他理论上的东西不必讲太多,编程讲的就 ...
- label用js,jquery取值赋值,以及怎么在后台取值
label标签在JS和Jquery中使用不能像其他标签一样用value获取它的值: 可以这样: JS: var label=document.getElementByIdx_x("id&qu ...