我不想找到所有最小生成树,但我想知道其中有多少,这是我考虑的方法:
- 使用 prim 或 kruskal 算法找到一棵最小生成树,然后找到所有生成树的权重,当它等于最小生成树的权重时,递增运行计数器。
我找不到任何方法来找到所有生成树的权重,而且生成树的数量可能非常大,所以这种方法可能不适合这个问题。由于最小生成树的数量是指数级的,因此将它们计数起来并不是一个好主意。
- 所有的权重都是正数。
- 我们也可以假设图中没有权重出现超过 3 次。
- 顶点数将小于或等于 40,000。
- 边数将小于或等于 100,000。
图中只有一棵最小生成树,其中顶点的权重不同。我认为找到最小生成树数量的最佳方法必须是使用此属性。
编辑:
我找到了解决这个问题的方法,但我不确定它为什么有效。谁能解释一下。
解决方案:求最小生成树长度的问题是众所周知的;寻找最小生成树的两种最简单的算法是 Prim 算法和 Kruskal 算法。在这两者中,Kruskal 的算法以权重递增的顺序处理边缘。不过,克鲁斯卡尔算法有一个重要的关键点需要考虑:当考虑按权重排序的边列表时,边可以贪婪地添加到生成树中(只要它们不连接已经以某种方式连接的两个顶点)。
现在考虑使用 Kruskal 算法的部分形成的生成树。我们已经插入了一些长度小于 N 的边,现在必须选择几条长度为 N 的边。算法规定,如果可能,我们必须在任何长度大于 N 的边之前插入这些边。但是,我们可以以我们想要的任何顺序插入这些边。还要注意,无论我们插入哪条边,它都不会改变图的连通性。(让我们考虑两个可能的图,一个具有从顶点 A 到顶点 B 的边,而另一个没有。第二个图必须将 A 和 B 作为同一连通分量的一部分;否则从 A 到 B 的边将被插入到一点。)
这两个事实一起意味着我们的答案将是使用 Kruskal 算法插入长度为 K 的边(对于 K 的每个可能值)的方法数的乘积。由于最多有三个任意长度的边,因此可以暴力破解不同的情况,并且可以在每个步骤之后像往常一样确定连接的组件。