「区间二分图」贪心匹配的正确性

U 群里一位群友(其实他是我学长)提出的问题,我觉得很有趣的,记录下来。证明的记号用的比较「口语化」。

question

上图该出了一个算法,我们要证明这一算法确实给出了图中所示二分图的一个最大匹配。

Proof. 我们用该算法构造一个大小相同的点覆盖,再由 König 定理即可证明最优性。

设那些个区间在 RR 中,单点在 LL 中。方便起见,我们 ii 表示左部的 ii 号点,用 [U,V][li,ri][U, V] \subset [l_i, r_i] 这样的区间表示一个 ii 出边集合的子集。而对于右部点,我们也直接用某个数字 vv 表示,这和左部点记号有重合,下面的论证读者要自行分辨哪个数字是左部点,哪个是右部点。

维护一个集合 SS,初始时 S=S=\varnothing

在第 ii 步循环中:

  1. 如果 ii 点可以找到对应的 left most 的顶点,记为 pip_i,则令 SS{i}S\gets S\cup \{i\}
  2. 如果不行,则对 [li,ri][l_i,r_i] 这一个区间里的每个点 vv,在 LL 中找到点 uu,使得 pu=vp_u=v。然后 S(S\{u}){v}S\gets (S \backslash \{u\}) \cup \{v\}(对每个 vv 都弄一次,如果这个 uu 之前就变成 vv 了,则不需要做这个操作,不妨把这个操作成为「把 uu 换下来」)。

我们归纳证明这一循环不变式:在第 ii 步循环结束后,SS 覆盖了 k=1i[lk,rk]\displaystyle \bigcup_{k=1}^i [l_k,r_k] 这些个边。(下面过程中有两层归纳,我们用不同颜色区分)

  • 第一个 case 显然。

  • 第二个 case:显然 [li,ri][l_i,r_i] 被覆盖了(因为里面的每个点都被加上去了)。而对于 ii 之前的 kk,我们再用一次归纳法:在 [li,ri][l_i,r_i] 这些个点全部被换上来后,还是有: 1ki1\forall 1\le k\le i-1[lk,rk],[l_k,r_k] 是被覆盖的:

    • 如果 kk 当时找到了 left most 的点,而且到外层第 ii也没被换下来,则这个是显然成立的。

      注意这一部分是不需要内层归纳奠基的。

    • 如果 kk 当时找到了 left most 的点,而且在外层第 ii之前被换下来。

      假设是在外层第 i<ii' < i被换下来,则在外层归纳的第 ii'中已经保证 [lk,rk][l_k, r_k] 被覆盖。

      而「换下来」的操作只会增加 SS 中属于 RR 的点,所以 [lk,rk][l_k,r_k] 之后仍然是被覆盖的。

      注意这一部分是不需要内层归纳奠基的。

    • 如果 kk 当时没有找到 left most 的点,则外层第 kk的时候已经把 [lk,rk][l_k,r_k] 对应的匹配邻居换下来了,这时候 [lk,rk][l_k, r_k] 是被覆盖的。

      而「换下来」的操作只会增加 SS 中属于 RR 的点,所以 [lk,rk][l_k,r_k] 之后仍然是被覆盖的。

      注意这一部分是不需要内层归纳奠基的。

    • 如果 kk 当时找到了 left most 的点,而且其就是在外层第 ii被换下来的,于是 pk[li,ri]p_k\in [l_i,r_i],我们考虑 [lk,rk][l_k,r_k] 这里面的边:

      • [lk,li)[l_k, l_i) 这之间的边肯定被之前的点覆盖(不然 kk 不会选择 pklip_k \ge l_i)。

        「被之前的点覆盖」这里的推理如下:

        • 如果 k=1k=1,则 pk=lkp_k=l_k。又因为 rkrir_k\le r_i,所以 [lk,rk][li,ri][l_k,r_k]\subset [l_i,r_i],把 [li,ri][l_i,r_i] 覆盖了也就把 [lk,rk][l_k,r_k] 覆盖了。

        • 如果 k>1k>1,则这里用一下内层归纳奠基归纳kk 的时候,j=1k1[lj,rj]\displaystyle \bigcup_{j=1}^{k-1} [l_j,r_j] 都被覆盖了,和算法执行前 k1k-1 步的效果是一样的,所以可以说「被之前的点覆盖」。

      • [li,ri][l_i,r_i] 中的边自然被覆盖。

      • 而因为 rkrir_k\le r_i,所以没有更右边的边了。

      综上这些个边全部被覆盖了。

外层归纳完成。\Box