标签:
题目大意:有一个人,想看N场表演,每场表演需要看K次
现在给出每场表演的周安排,和表演的截止日期
问这个人能否看完所有电影
解题思路:二分图多重匹配可以做,最大流也可以做,这里只讲二分图最大匹配
讲350天设置成一个点集,将每场表演设置为另一个点集,容量为需要看的次数,两者间的关系就是该天是否有表演
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 360
#define M 10010
#define S 25
int day[7], g[N][S], vlink[S], link[S][N], cap[S];
int n, tot, Sum;
bool vis[N], route[S];
void init() {
memset(vis, 0, sizeof(vis));
memset(g, 0, sizeof(g));
memset(vlink, 0, sizeof(vlink));
tot = 0;
scanf("%d", &n);
int d, w;
Sum = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < 7; j++) {
scanf("%d", &day[j]);
}
scanf("%d%d", &cap[i], &w);
Sum += cap[i];
for (int j = 0; j < 7; j++) {
if (day[j]) {
for (int k = 0; k < w; k++) {
g[k * 7 + j][i] = true;
vis[k * 7 + j] = true;
}
}
}
}
}
bool dfs(int u) {
for (int i = 0; i < n; i++) {
if (!route[i] && g[u][i]) {
route[i] = true;
if (vlink[i] < cap[i]) {
link[i][++vlink[i]] = u;
return true;
}
for (int j = 1; j <= vlink[i]; j++) {
if (dfs(link[i][j])) {
link[i][j] = u;
return true;
}
}
}
}
return false;
}
void solve() {
int ans = 0;
for (int i = 0; i < 350; i++)
if (vis[i]) {
memset(route, 0, sizeof(route));
if (dfs(i)) {
ans++;
}
}
if (ans == Sum)
printf("Yes\n");
else
printf("No\n");
}
int main() {
int test;
scanf("%d", &test);
while (test--) {
init();
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ - 1698 Alice's Chance (二分图多重匹配)
标签:
原文地址:http://blog.csdn.net/l123012013048/article/details/47295503