题目大意:
首先输入的是一个整数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;
}