CF1305G 题解

这篇博客介绍了如何利用Boruvka算法解决CF1305G问题。作者通过建立图,分析联通块,并采用贪心策略让小的节点邀请大的节点,形成树状结构。在确保图联通的基础上,利用最小生成树的概念,讨论了Prim、Kruskal和Boruvka算法,特别是Boruvka算法的实现细节和高维前缀和的应用,强调了处理最大边权和次大边权的问题。

CF1305G

可以算说我自己做出来的 3500 3500 3500 题吧。虽然这是很多年前的题。

这个东西我们可以尝试一下建图,也就是如果两个点是朋友关系我们可以使其连边。

然后会发现有很多的联通块,那么我们不妨对于一个联通块来考虑。

我们贪心得想肯定要让小的邀请大的点。然后邀请的情况肯定构成一个树,也就是邀请的边数是点数 − 1 -1 1

因为不能重复邀请。

我们考虑这个树的情况需要使用,会想到最大生成树。然后要如何设置边权?可以发现对于一条边本质上两边都可以使用那么边权就是 a u + a v a_u + a_v au+av。但是每一个点肯定需要一次被加入,那么就需要减去所有点的点权。

但是我们第一个选择的点不知道是谁,总不可能暴力枚举吧,发现可以建立一个 0 0 0 节点,链接所有的节点,这样第一个点的贡献也可以计算了。

现在可以保证整张图是联通的,我们计算最小生成树即可。

最小生成树总共有 3 3 3 种求法。 p r i m prim prim k r u s c a l kruscal kruscal 都需要预先知道全部的边。那么我们可以使用 B o r u v k a Boruvka Boruvka。在计算的过程中我们只需要进行高维前缀和即可。

因为最大的边权可能被计算过了,那么我们维护一个和最大边权所属联通块不同的次大边权即可。

第一次写 B o r u v k a Boruvka Boruvka 感觉细节特别多,最后还是重构一遍过的。


#include <bits/stdc++.h>
using namespace std;

//#define Fread
//#define Getmod

#ifdef Fread
char buf[1 << 21], *iS, *iT;
#define gc() (iS == iT ? (iT = (iS = buf) + fread (buf, 1, 1 << 21, stdin), 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值