1. 先看懂题目信息:P3366 究竟想让你做什么
1.1 题面信息剥开之后只剩一件事
洛谷P3366【模板】最小生成树,大概是很多算法竞赛选手写的第一道带“模板”标签的图论题。页面上的题目信息非常干净:给出一张无向图,有N个点,M条边,每条边有一个长度或者说边权,最终要求输出最小生成树的各边长度之和。N不超过5000,M不超过200000,输入顺序就是先给N和M,然后给M行三元组,表示一条边连接哪两个点、权值是多少。
理解这类题目有一个很重要的心态:不要被“模板”两个字吓到。它的意思是说,出题人刻意砍掉了所有干扰信息,不给你设计复杂背景,不设置小聪明样的输出陷阱,就是为了让你在这里把最小生成树的算法本身练到滚瓜烂熟。你可以把这道题理解成“算法动作的考场”,而不是“阅读理解考场”。真正要考察的只有三个动作:能否正确建模最小生成树、能否正确实现算法、能否处理图不连通这种边界情况。
看到 N=5000、M=200000 这个范围,实际上也是在传递一条信息:常规复杂度的解法都在安全区内。比如 Kruskal 的 O(M log M) 可以轻松通过,朴素 Prim 的 O(N^2) 也才2500万次操作量级,堆优化 Prim 的 O((N+M) log N) 更是绰绰有余。要是哪份题解写出 O(NM) 甚至 O(N^2 log N) 的复杂度,在这个数据范围下反而是需要警惕的。数据规模往往暗示了出题人想让你采用哪种算法,这是做题时最先应该养成的直觉。
1.2 模板题的隐藏要求:图不连通就输出 orz
如果只是输出边权和,这题就太单调了。P3366 在题面里埋了一个小小的边界条件:如果该图不连通,则输出 orz。这个 orz 看起来像彩蛋,实际上是对“最小生成树是否存在”的一次考察。
最小生成树的定义建立在树的基础上,树就是连通且无环的图。一个有N个点的无向图,如果本身不是连通的,那就不可能存在一棵覆盖所有点的生成树,自然也就没有最小生成树。判断方法很多,但写成模板的时候要特别注意:Kruskal 里维护一个变量 cnt,记录成功合并的次数;只有当 cnt 达到 N-1 时,