Codeforces 1108F

题意

给定1个无重边自环的无向联通图。你可以增加各边的边权,边权每增加1,算作1次操作。

询问最小的操作数,使得MST不变,且MST方案唯一

题解

1种很直观的思路是,执行Kruskal的途中,若某边权为\(val\)的边\(e\)会导致环的出现,且该中存在其它边权为\(val\)的边;为了方案的唯一性,应使\(e\)不能被选,将其边权加1即可。

很遗憾的是,惊喜之下我混淆了环与联通块的概念,将代码写成了这样。当时以为反正\(val\)为最大边权,则环与联通块可以等价;殊不知由于相同边权的存在,会对\(val\)不在环中而在联通块中的情况误判。一定要仔细考虑真正的阶段以及同阶段元素的相互作用!类似的经验也可以看Codeforces 459E

最直接的做法是求树上\((u,v)\)间的边权最大值。先求出1种MST,结合树上倍增即可。

或者考虑在上述的错误思路上打补丁——排除环内最大值与联通块内最大值不等价的情况

考虑该情况出现的条件,当且仅当\((u,v)\)在边权为\(val\)的边出现前就已经联通。

故只要在访问边权为\(val\)的边前,先统一标记两顶点已经联通的边,并在实际求解中跳过,即可使环与联通块等价。其余步骤不变,不再赘述。

[代码见此](https://github.com/littlewyy/OI/blob/master/cf 1108F)。时间复杂度\(O(NlogN+MlogM)\)

当然,如果对Kruskal有更好的理解,就不必这样兜弯子。

Kruskal本质上的阶段是边权大小(而不是边),因而应对每堆边权为\(val\)的边整体考虑

则显然加入这堆新边前顶点已联通的边不可能被选,直接跳过;剩余的边照常Kruskal,若某边不能加入MST中,则应将该边边权加1。累计即为所求。

回顾与思考

心静才能做好题。急躁只能坏事。

欲速则不达。请1点点磨平你性格中的缺陷,深度思考,谨慎做题。

posted @ 2019-05-16 16:16  littlewyy  阅读(280)  评论(0编辑  收藏  举报