D2. Mocha and Diana (Hard Version)
题意
给出两个森林,两个森林中的点编号都是从 1…n,第一个森林中有 m1 条边,第二个森林中有 m2 条边,可以进行连边操作,每次对两个森林中的顶点 (u,v) 进行连边,并要求每次连边之后两个都仍是森林(即不会出现环,注:一棵树也是森林),求最多能连多少条边,并输出每次连的边。
数据范围:N⩽105
思路
引理:最多连的边数一定是 min(n−m1−1,n−m2−1)。
证明:
不妨令 m1⩽m2。
-
首先,最多连的边数一定不会超过 n−m1−1,因为当森林变为一棵树的时候,边数最多为 n−1,现有 m1 条边,则最多不能加超过 n−m1−1 条边。
-
其次,如果连的边数小于 n−m1−1 则说明,第一个森林中至少还有两棵树,如果当前已经不能连边,则说明,在这两棵树中分别任取两个顶点,在第二个森林中,都是在一棵树中的,如果对于任意两个节点都有这个性质,那么第二个森林就已经是一棵树了,这与 m2⩽m1 矛盾,因为不可能第一个森林还没变为一棵树,第二个森林已经提前变为一棵树。
综上,原命题得证。
QED
也就是说:达成最大连边数,当且仅当,两个森林中至少有一个森林只有一棵树。
下面考虑如何求出每次连的边,按照下述步骤进行:
下面给出一个例子:
步骤2中,在森林1中不包含1号顶点的树只有3号节点,在森林2中不包含1号顶点的树只有2号顶点,最后直接将2和3连接即可。
下面给出这样操作的正确性证明:
证明:
令森林1中的连通点集合(也就是一棵树中的点)记为 Si,森林2中的连通点集合记为 Ti,不妨假设顶点1属于 S1,T1。
通过步骤一我们可以发现,在森林1中,如果存在 S1 和 S2,则说明1号顶点不能和 S2 中任意的一个顶点进行连边,这说明在森林2中,顶点1和 S2 中的点一定在同一棵树中,也就是 S2⊆T1。
那么接下来,如果取 ∀u∈Si,(i⩾2),则有 u∈T1,故 u∈Tj,(j⩾2)。
于是我们可以取 ∀v∈Tj,(j⩾2),连接 (u,v),这样就能将 S1,Si 和 T1,Tj 同时合并。
也就是说下面这样的操作具有正确性(即不会连成环)。
设森林1中一共有 n 棵树,森林2中一共有 m 棵树,设 min=min(n,m)。
那么通过连接:
(u2,v2),(u2∈S2,v2∈T2)(u3,v3),(u3∈S3,v3∈T3)⋯(ui,vi),(ui∈Si,vi∈Ti)⋯(umin,vmin),(umin∈Smin,vmin∈Tmin)
就一定会将其中一个森林最终转换为只有一棵树,由引理得知,达到题目要求。
QED
用并查集维护集合,总复杂度 O(NlogN),其实并查集复杂度远小于 O(logN)。
点击显/隐代码
参考
CSDN-RunningBeef-D2. Mocha and Diana (Hard Version)