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),

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

被折叠的 条评论
为什么被折叠?



