【校内模拟】【18-10-16】 华莱士 【环套树】

(拖更N天终于想起来我还有博客
(校内模拟的题面&代码联赛后解除封印~)

题解

1.0 认(hu)真(luan)分析

这道题直到考试完我都没怎么看懂……(太弱了)

其实题意非常简单:在保证每个点只有入度为1的情况下,计算出联通所有点所需的最小代价。

如果这题给的不是无向边而是有向边,我们自然可以想到Kruskal一波解决。问题就在于,这是有向边,而我们需要的是一个联通图。

那么,如果使用Kruskal求出最小生成树,最后再加上一条花费最小的边,使得树上出现一个环,似乎就能解决这个问题了?

很遗憾,这个算法是错的,在考场上只能得到50分(实际上是因为数据水了)

1.1 继续分析

首先我们弄清楚一个概念:环套树。

顾名思义,环套树还真就是一个环+一棵树的结构。那么运用在这道题里,我们实际上就是求给定图中的最小环套树.

吗?

仅仅这样还不够,因为可能图中存在多个环套树,也许还有零散的点构成树,因而最后我们求得的实际上是一个环套树森林。

那么在这个求得的过程中,我们还是考虑Kruskal的加边方式,也就是按权值从小到大依次加边。那么这其中肯定会牵扯到合并两个联通块的问题,这又该怎么解决呢?

下面的解说(又)引自神仙ZXY的博客

显然合并环套树与环套树是不够优的。
简单树和环套树合并后的图是环套树。
简单树与简单树合并后的图仍然是简单树。
简单树内部加边就成了环套树。
只需要考虑上面四种情况,如果最后有节点不在环套树森林中,肯定无解。

为了查询每个联通块自身的属性,我们可以在并查集的根节点上进行维护。这样一来,只需要在Kruskal的合并部分加上几个关于联通块属性的特判就可以了。

总结

有的时候,当我们发现一个问题与另一个问题相近,就意味着我们只需要对原有算法进行些许改动,让它适合这道题就可以了。因而在考试时不要轻易否决每一个念头,说不定那就是解出这道题的关键呢~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值