优先内向树扩张算法 学习笔记

大量参考集训队爷的博客link

这个算法是用来解决最小内向森林问题的,可以解出有\(k\)棵树时的最优解,时间复杂度是\(O(mlogm)\)

注意到图的生成内向森林是一个拟阵

所以我们可以由考虑从\(i+1\)棵内向树推出\(i\)棵内向树时的答案,每次贪心地扩展最小的边

算法思路大致如下:

1、用堆维护当前所有内向树及其扩展代价。初始内向树是\(n\)个点,每个点的代价是其最小出边。

2、选择当前扩展代价最小的内向树,如果没有树可以扩展,则退出。

否则进行扩展(即从根连其最小出边到其他树),记录答案。

3、更新当前被修改的内向树的“扩展代价”。

具体扩展的方式就是不停地加入堆顶的边如果不成环就退出,否则就合并两个堆,在合并之前注意维护连上那条边的代价

然后返回2

模板

最小树形图

HDU 2020 Multi-University Training Contest 4 Joyful Party

建图发现是最小内向森林

但是发现他一条边连向的点太多了,但是线段树优化建图不现实

于是考虑写个线段树维护每个环上有哪些点

每次找出一条边中能到达的最小的点进行计算

注意到每一次选点都至少等效地会减少原图中的一个点(不管是连边扩展树还是把几棵树连成环)

所以复杂度是\(O((m+n)logm)\)

code

posted @ 2020-10-08 12:32  deaf  阅读(213)  评论(0编辑  收藏  举报