8.29 活着的意义

时间:2019-08-29
本文章向大家介绍8.29 活着的意义,主要包括8.29 活着的意义使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题意

给一张\(n\)个点\(m\)条边的无向图,有一个对于这个无向图的操作,即去除图中的一个生成森林(即所有连通块中生成树的集合)。不断对该无向图进行操作直到该图中的边全部被删除。对于每一条边,输出他是在第几次被删除的。

如果有多种方案,输出其中一种即可


解法

首先我们有一个很好想的\(O(MN)\)暴力

遍历每一条边,每次进行生成树操作:具体来说,就是每次开一个并查集,如果该边的两个端点不在同一个连通块中,则把它们联通,并且把该边从边集中删除;否则跳过该边

考虑我们如何对暴力算法进行优化

如果我们开若干个并查集,每次对于一条边,如果在\(1\)号并查集中它的两端所连接的点在一个连通块内,我们就在\(2\)号并查集中进行插入,以此类推...

通过上述算法,我们可以求出每一次操作后形成的生成森林

但是我们会发现,这个算法和原来相比,不仅时间复杂度没有改观,空间复杂度反而变得更劣了

但是这个算法的思想却有一定的启发性

我们可以发现一个性质:对于一条边,如果它可以在第\(i\)号并查集中插入,那么它也一定可以在\(i+1...n\)号并查集中插入

这个可以用反证法证明,也可以意会理解一下

发现了这个性质以后,我们就可以二分出第一个可以插入的并查集编号了

这样时间复杂度由\(O(MN)\)优化到了\(O(MlogM)\)

但是空间复杂度仍然无法承受

此时我们可以用哈希表优化空间

我们把若干个并查集排在一起,可以看做一个若干行\(n\)列的矩阵

把每个矩阵的坐标\((x,y)\)映射成某个数

在操作的过程中我们最多插入\(2M\)个不同的点

所以并查集只需要开\(O(2M)\)的空间即可

还有一个骚操作:用指针动态开点??!但是不太会用指针,就先咕着吧


代码

原文地址:https://www.cnblogs.com/VeniVidiVici/p/11432037.html