POJ2239 Selecting Courses【二部图最大匹配】

主题链接:

http://poj.org/problem?id=2239


题目大意:

学校总共同拥有N门课程,而且学校规定每天上12节可,一周上7天。

给你每门课每周上的次数,和哪一天哪一节

上的。假设有多门课程在同一天同一节课上。那么你仅仅能选择当中一门。那么问题来了:最多能同一时候选多少

门课而不发生冲突呢。


输入说明:

先给你一个N。表示有N门课。接下来N行,每行第一个数字x,表示这门课每周上几节。接下来是x对数。第

一个数D表示是这一周哪一天上的,第二个数C表示是这一天哪一节课上的。


思路:

将这道题来看做二分图匹配问题。

建立一个二分图,一边代表课程,一边代表某一节课(将一周7*12节课按

1~7*12来排列)。将课程和该课程上的某一节课相应建边,再求这个二分图的最大匹配数就可以。这里用匈牙

利DFS版来做。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 330;

int Map[MAXN][MAXN];
int Mask[MAXN];
int N,M;
int cx[MAXN],cy[MAXN];

int FindPath(int u)
{
    for(int i = 1; i <= M; ++i)
    {
        if(Map[u][i] && !Mask[i])
        {
            Mask[i] = 1;
            if(cy[i] == -1 || FindPath(cy[i]))
            {
                cy[i] = u;
                cx[u] = i;
                return 1;
            }
        }
    }
    return 0;
}

int MaxMatch()
{
    int res = 0;
    for(int i = 1; i <= N; ++i)
        cx[i] = -1;
    for(int i = 1; i <= M; ++i)
        cy[i] = -1;

    for(int i = 1; i <= N; ++i)
    {
        if(cx[i] == -1)
        {
            for(int j = 1; j <= M; ++j)
                Mask[j] = 0;
            res += FindPath(i);
        }
    }
    return res;
}

int main()
{
    int a,b,id;
    while(~scanf("%d",&N))
    {
        memset(Map,false,sizeof(Map));
        M = 7*12;

        for(int i = 1; i <= N; ++i)
        {
            scanf("%d",&id);
            for(int j = 1; j <= id; ++j)
            {
                scanf("%d%d",&a,&b);
                Map[i][(a-1)*12+b] = 1;
            }
        }
        printf("%d\n",MaxMatch());
    }

    return 0;
}


版权声明:本文博主原创文章,博客,未经同意不得转载。

posted @ 2015-10-02 15:10  yxwkaifa  阅读(283)  评论(0编辑  收藏  举报