当前位置: 首页 > news >正文

Kruskal重构树学习笔记(C++)

Kruskal重构树学习笔记

提示:

学习Kruskal重构树之前建议先了解一下Kruskal算法,虽然不了解这个影响不会很大

一定要了解一下并查集的算法

接下来如果想要应用Kruskal重构树,一定要了解一下LCA算法

什么是Kruskal重构树

这里先简单说明一下Kruskal算法:

Kruskal算法依托于并查集算法实现

一张图的边排序,从小到大依次将每一条边加入最小生成树,如果加入后会形成环,则不加入

Kruskal重构树的算法与其基本一致:

Kruskal重构树算法依托于并查集算法实现

(这里文字描述可能优点绕口,建议先看图再回来看文字)

一张图的边排序,从小到大依次尝试每一条边

将边的两个节点的根节点(当一棵树只有一个节点时,它就是自己的根节点)连接到一个新创建节点上

赋予新创建节点权值,权值等于这条边的边权

循环,直至形成一棵树(所有点都在一个集合中)

这里写图片描述

*注:上图来自CSDN博主wu_tongtong:http://blog.csdn.net/wu_tongtong

第一次合并,1和4间边权最小,合并1和4

在这里插入图片描述

第二次合并,3和6间边权最小,合并3和6

第三次合并,1和2间边权最小,合并2和1的根节点
在这里插入图片描述

第四次合并,5和4间边权最小,合并5和2的根节点
在这里插入图片描述

Kruskal重构树的性质

1、二叉树

2、原树两点间路径上边权的最大值 = 新树两点间路径上点权的最大值

也就是说原树中两点之间路径上边权的最大值等于新树上两点的LCA的点权

3、子节点的点权小于等于父节点(大根堆)

Kruskal重构树的实现

讲解完了思路,接下来实现具体的代码

void exKruskal(int n) {
	edge t;
	int u, v;
	while (!p_q.empty()) {//p_q为优先队列(小根堆)
		t = p_q.top();
		p_q.pop();//取出最短边
		u = t.u; v = t.v;
		if (is_in_same(u, v)) continue;//会形成环
		//不会形成环
		n++;//从n + 1开始分配
		fa[n] = fa[u] = fa[v] = n;
		son[n][0] = u; son[n][1] = v;//连接
		value[n] = t.p;//赋值
	}
}

这个只是便于理解的版本,实现方式多种多样,这里不一一列举

Kruskal重构树例题

1、P1967[NOIP2013 提高组] 货车运输

2、P2245 星际导航

3、P4197 Peaks

4、P4768 [NOI2018] 归程

(已按难度升序排序,洛谷中每道题都有相应的题解)

相关文章:

  • 衡水安徽网站建设/百度关键词推广2元一天
  • 哪个公司可以做网站/深圳20网络推广
  • 石家庄网站托管公司/最新域名解析
  • 网站带搜索功能怎么做/河北seo网络推广
  • 天津卓荣建设集团网站/天津关键词优化网排名
  • 网站开发需要几个人/春哥seo博客
  • 电商erp迁往云端必须注意的5件事
  • docker-compose 搭建伪分布模式redis cluster集群
  • JS逆向之补环境过瑞数详解
  • 【PR #5 C】和平共处(整体二分)
  • 数组、对象操作方法
  • 2023-01-16 阿里SMS短信接口使用
  • 【linux kernel】Linux设备驱动模型 | bus
  • HTML的body元素
  • Spring Boot(五十四):SpringBoot事件监听机制
  • Fastdfs分布式文件系统原理浅析
  • 3-2存储系统-主存与CPU的连接外部存储器
  • 20230116英语学习