POj 2239 Selecting Courses(二分图匹配)

题目大意:

首先输入的是一个整数n,代表Li Ming学院的课程数,然后输入n行,每行代表一个课程,以整数t开头,代表上课的课程时间,然后是t组p,q的值,p代表的数星期数,q代表的是节数。输出的结果是Li Ming能够上的最多的课程(这些课程不会有上课时间的冲突)。

解题思路:

一道典型的二分图匹配的问题,关键的是怎么建立二分图,刚开始的时候我是把课程编号都加入到二分图的两个点集中,这样的话会增加建图的难度,可能也是错误的建图方式。后来看了网上的建图方式,感觉挺巧妙的,哎,还是二分图匹配的问题做的少。下面的程序是以课程编号作为二分图的一个点集,另一个点集包含的是课程的上课时间(p-1)*12+q,然后将课程与上课时间建立对应的关系,直接用二分图匹配算法,就ok了!

代码:

#include<iostream>
#include<fstream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<sstream>
#include<cassert>
using namespace std;
#define LL __int64
const int MAXN=1000;
int uN,vN;
bool g[MAXN][MAXN];
int xM[MAXN],yM[MAXN];
bool chk[MAXN];

bool SearchPath(int u){
    int v;
    for(v=0; v<vN; v++){
        if(g[u][v] && !chk[v]){
            chk[v]=true;
            if(yM[v]==-1 || SearchPath(yM[v])){
                yM[v] = u; xM[u] = v;
                return true;
            }
        }
    }
    return false;
}

int MaxMatch(){
    int u, ret = 0;
    memset(xM,-1,sizeof(xM));
    memset(yM,-1,sizeof(yM));
    for(u=0; u<uN; u++){
        if(xM[u] == -1){
            memset(chk,false,sizeof(chk));
            if(SearchPath(u)) ret++;
        }
    }
    return ret;
}

int main(){
    int n,t,x,y;
    while(~scanf("%d",&n)){
        uN=n;vN=7*13;
        memset(g,false,sizeof(g));
        //memset(link,-1,sizeof(link));
        for(int i=0;i<n;i++){
            scanf("%d",&t);
            for(int j=0; j<t; j++){
                scanf("%d%d",&x,&y);
                g[i][(x-1)*12+y]=true;
            }
        }
        printf("%d\n",MaxMatch());
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值