1 条题解
-
1
题意
给你一个时限,一个工作的时间长度,和可以工作的日子(星期日到星期六),让你求出是否可以拍完所有的电影。
题解
建图是关键,我们可以列出两列,第一列是不同的电影,第二列是星期的日子,然后开始连边。当然,这时我们发现会有一些不和谐,也就是说,因为每部电影的时限不同,所以有一部分(星期)只能拍某部电影,而其他的不行。所以,我想到了,将其分开,也就是个管个的——时限久的可以连上时限短的(星期),最后做一遍最大流就可以了。
标程
#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
- 上传者