P1231 教辅的组成(拆点)

传送门

思路:对课本拆点,限制课本使用次数为1,然后这样连边,课本发出点->练习册,容量为1,答案->课本接收点,容量为1

源点->答案,容量为1,练习册连汇点,容量为1,最终形成源点->答案->课本接受点->课本发出点->练习册->汇点的网络图

然后跑网络流,这样就能得到最大匹配成功数了

AC代码:

int main() {
    //freopen("test.txt", "r", stdin);
    scanf("%d%d%d", &n1, &n2, &n3);
    scanf("%d", &m1);
    s = n1*2 + n2 + n3 + 1, d = s + 1;
    for (int i = 1; i <= n1; i++) {//对课本拆点
        add(i, i + n1, 1);
        add(n1 + i, i, 0);
    }
    for (int i = 1; i <= m1; i++) {//课本出发点->练习册
        int a, b; scanf("%d%d", &a, &b);
        add(a + n1, b + n1 * 2, 1);
        add(b + n1 * 2, a + n1, 0);
    }
    scanf("%d", &m2);
    for (int i = 1; i <= m2; i++) {//答案->课本接受点
        int a, b; scanf("%d%d", &a, &b);
        add(b + n1 * 2 + n2, a, 1);
        add(a, b + n1 * 2 + n2, 0);
    }
    for (int i = 1; i <= n3; i++) {//源点->答案
        add(s, i+n1*2+n2, 1);
        add(i+n1*2+n2, s, 0);
    }
    for (int i = 1; i <= n2; i++) {//练习册->汇点
        add(i + n1*2, d, 1);
        add(d, i + n1*2, 0);
    }
    printf("%lld\n", dinic());
    return 0;
}

 

posted @ 2021-04-06 21:09  cono奇犽哒  阅读(75)  评论(0)    收藏  举报