1 条题解

  • 0
    @ 2025-8-24 21:58:16

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar zac2010
    a vegedog

    搬运于2025-08-24 21:58:16,当前版本为作者最后更新于2023-05-24 21:17:39,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    解题思路

    先声明一下:此题不是 NPC。毕竟出题人还不至于能在多项式时间复杂度内爆切 NPC 问题。

    一种不正确的最初想法:把每个筐拆成 33 个点 ui,ui+m,ui+2×mu_i,u_i+m,u_i+2 \times m,所有 viv_iuiu_i 拆后的三个点连边,跑二分图的最大匹配。

    hack:
    Input:
    1
    2 2 3
    1 1
    2 1
    2 2
    Output:
    2
    1 2
    

    在这里可能会因为边的遍历顺序问题而先跑边 (2,1)(2,1) 而导致答案变成 11

    那么接着就是这道题奇特的建图方式了。不妨在上述的建图方式为基础的情况下把所有的 u,u+m,u+2×mu,u+m,u+2 \times m 两两之间连边,然后跑一般图的最大匹配(改为一般图的原因:前面三个点的两两连边会形成奇环),最后答案就是最大匹配数 n-n

    来证明一下这个结论。

    对所有的 ui,ui+m,ui+2×mu_i,u_i+m,u_i+2\times m44 种情况讨论:

    1. 其中有 00 个匹配点。

      本来的贡献应该是 11。内部点必然恰好有一组匹配。减去匹配在这种情况下即等于减去 00,所以贡献还是 11

    2. 11 个。

      本来的贡献应该是 11。会发现内部必然有一组匹配,和那一个匹配点所处的匹配一加,贡献为 22。所以多出来 11,刚好是减去匹配点个数。

    3. 22 个。

      本来的贡献应该是 00。注意到三个点不可能再出现内部匹配的情况了,所以刚好减去匹配点个数。

    4. 33 个。

      22 个的情况同理。

    所以对于任意一组“每个球都放在一个框中”的匹配,拿匹配数 n-n 一定等于答案。为了使答案最大,当然是取最大匹配了。且求最大匹配时我们优先对球进行增广,然后再对框子所表示的点进行增广。这样便可保证“每个球都放在一个框中”。

    代码

    给个这道题的重点部分(建图的部分):

    //输入+建边
    scanf("%d%d%d", &n, &m, &e);
    for(int i = 1; i <= m; i++){
    	Add(i + n, i + m + n), Add(i + m + n, i + n);
       Add(i + n, i + 2 * m + n), Add(i + 2 * m + n, i + n);
       Add(i + m + n, i + 2 * m + n), Add(i + 2 * m + n, i + m + n);
    }
    for(int i = 1; i <= e; i++){
    	int v, u; scanf("%d%d", &v, &u);
    	Add(v, u + n), Add(v, u + m + n), Add(v, u + 2 * m + n);
    	Add(u + n, v), Add(u + m + n, v), Add(u + 2 * m + n, v);
    }
    
    //之后跑一般图的最大匹配
    
    • 1

    信息

    ID
    3220
    时间
    1000ms
    内存
    250MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者