1 条题解

  • 1
    @ 2025-4-3 21:00:10

    题意

    给你一个时限,一个工作的时间长度,和可以工作的日子(星期日到星期六),让你求出是否可以拍完所有的电影。

    题解

    建图是关键,我们可以列出两列,第一列是不同的电影,第二列是星期的日子,然后开始连边。当然,这时我们发现会有一些不和谐,也就是说,因为每部电影的时限不同,所以有一部分(星期)只能拍某部电影,而其他的不行。所以,我想到了,将其分开,也就是个管个的——时限久的可以连上时限短的(星期),最后做一遍最大流就可以了。

    标程

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    int T, n, limit[25], able[10], bmap[25][510], maxw;
    int cx[510], cy[25][510];
    bool vis[25];
    
    bool findpath(int u) {
        int i, j;
        for (i = 1; i <= n; i++) {
            if (bmap[i][u] && !vis[i]) {
                vis[i] = 1;
                if (cy[i][0] < limit[i]) {
                    cy[i][++cy[i][0]] = u;
                    return 1;
                } else {
                    for (j = 1; j <= cy[i][0]; j++) {
                        if (findpath(cy[i][j])) {
                            cy[i][j] = u;
                            return 1;
                        }
                    }
                }
            }
        }
        return 0;
    }
    
    bool mulmatch() {
        int ans = 0, s = 0;
        int i;
        memset(cx, 0, sizeof(cx));
        memset(cy, 0, sizeof(cy));
        for (i = 1; i <= maxw * 7; i++) {
            memset(vis, 0, sizeof(vis));
            if (!cx[i]) {
                if (findpath(i)) {
                    ans++;
                }
            }
        }
        for (i = 1; i <= n; i++) {
            s += limit[i];
        }
        return ans == s;
    }
    
    int main() {
        int i, j, k, w;
        scanf("%d", &T);
        while (T--) {
            memset(bmap, 0, sizeof(bmap));
            scanf("%d", &n);
            maxw = 0;
            for (i = 1; i <= n; i++) {
                memset(able, 0, sizeof(able));
                for (j = 1; j <= 7; j++) {
                    scanf("%d", &able[j]);
                }
                scanf("%d%d", &limit[i], &w);
                maxw = (w > maxw)? w : maxw;
                for (j = 1; j <= 7; j++) {
                    if (able[j]) {
                        for (k = 0; k < w; k++) {
                            bmap[i][k * 7 + j] = 1;
                        }
                    }
                }
            }
            if (mulmatch()) {
                printf("Yes\n");
            } else {
                printf("No\n");
            }
        }
        return 0;
    }    
    
    • 1

    信息

    ID
    699
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    8
    已通过
    1
    上传者