https://codeforces.com/contest/160/problem/D
众所周知连通图的mst可能有多个,现给定一个无向图(n、m<=1e5),要求判断每条边,是存在于所有的mst中,还是至少存在于一个mst中,还是不存在于任一mst中。
我们现在来考虑Kruskal的算法流程,首先对于边按权值排序,从小到大挨个添加(当两个端点不连通时)。当我们遇到若干条权值相同的边,且都满足添加条件时,则可以任选一条,这就是1、2的情况。而如果当前边的两端已经在同一点集中,这条边则不可能被添加,是第三种情况。接下来我们考虑如何区分前两种情况。
首先对于若干条相等的边,如果判断它可以连,就先把对应点集的祖先连接在一起,点集暂时不合并。就这样处理完之后,我们在当前图找桥,复杂度O(刚添加的边数)。桥边属于必选,剩下的边则是可选。然后第三步,则是把这些边两端的点集都合并起来,并把之前的连边信息清空,因为他们现在属于一个点集了,有公共的祖先,就不需要这些内部边了。这里所用到的一个技巧就是,用每个点集的祖先代表这个点集中的所有点,如果一个点集向另一个点集发出两条边,则相当于这两个祖先点连了两条重边,则这两条边都是可选;如果只有一条,那么就必须选择。然后这里的找桥算法也需要修改,为了支持重边的情况,之前算法中是不采用来自父亲的边,现在修改为不采用通向当前点u的这条边,其余通向父亲的重边是可以采用的。这样一来就不会误判桥了。
1 |
|