您的位置:首页 > 其它

POJ - 1698 Alice's Chance (二分图多重匹配)

2015-08-05 12:54 411 查看
题目大意:有一个人,想看N场表演,每场表演需要看K次

现在给出每场表演的周安排,和表演的截止日期

问这个人能否看完所有电影

解题思路:二分图多重匹配可以做,最大流也可以做,这里只讲二分图最大匹配

讲350天设置成一个点集,将每场表演设置为另一个点集,容量为需要看的次数,两者间的关系就是该天是否有表演

[code]#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 360
#define M 10010
#define S 25

int day[7], g
[S], vlink[S], link[S]
, cap[S];
int n, tot, Sum;
bool vis
, 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: