POJ2239-Selecting Courses-(匈牙利算法)

题意:n门课,每门各自有t个开课时间,在不冲突的情况下选最多课。

题解:把周p第q节课转化为数值sum,表示在一周7*12节课中排第几节,用二分图最大匹配。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;

int n,m;
vector<int>a[305];
bool vis[7*12+15];
int par[7*12+15];

bool dfs(int x)
{
    int len=a[x].size();
    for(int i=0;i<len;i++)
    {
        int next=a[x][i];
        if( !vis[next] )
        {
            vis[next]=true;
            if( !par[next] || dfs( par[next] ) )///next未被选中 或者 选next的那门课有别的时间段可以选
            {
                par[next]=x;///next这个时间段被第x门占用了
                return true;
            }
        }
    }
    return false;
}



int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(par,0,sizeof(par));///清空操作
        for(int i=1;i<=n;i++)
            a[i].clear();

        for(int i=1;i<=n;i++)
        {
            scanf("%d",&m);
            while(m--)
            {
                int p,q,sum;
                scanf("%d%d",&p,&q);
                sum=p*12+q;///在一周7*12节课中排第几节
                a[i].push_back(sum);
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            memset(vis,false,sizeof(vis));
            if(dfs(i))
                ans++;
        }
        printf("%d\n",ans);
    }

    return 0;
}
POJ2239

猜你喜欢

转载自www.cnblogs.com/shoulinniao/p/11332843.html