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

什么是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] 归程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WitheredSakura_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值