题目大意:
在大学里有许许多多的课程,现在小明需要去选择课程,他是一个爱学习的人,所以想尽可能多的选择课程,
在学校里有n个课程,并且在学校规定,每周里的每天有12节课,那么一周就有7*12节课。
分析:
二分图匹配。优点:适用于稀疏图,边较少,增广路较短。
#include<stdio.h>
#include<string.h>
#define MAXN 350
int g[MAXN][MAXN],Mx[MAXN],My[MAXN],Nx,Ny;
int chk[MAXN],Q[MAXN],prev[MAXN];
int MaxMatch(){
int res=0,i,v;
int qs,qe;
memset(Mx,-1,sizeof(Mx));
memset(My,-1,sizeof(My));
memset(chk,-1,sizeof(chk));
for(i=0;i<Nx;i++){
if(Mx[i]==-1){
int flag=0;
qs=qe=0;
Q[qe++]=i;
prev[i]=-1;
while(qs<qe&&!flag){
int u=Q[qs++];
for(v=0;v<7*12&&!flag;v++)
if(g[u][v]&&chk[v]!=i){
chk[v]=i;
Q[qe++]=My[v];
if(My[v]>=0)prev[My[v]]=u;
else{
int d=u,e=v;
flag=1;
while(d!=-1){
int t=Mx[d];
Mx[d]=e;
My[e]=d;
d=prev[d];
e=t;
}
}
}
}
if(Mx[i]!=-1) res++;
}
}
return res;
}
int main(){
// freopen("in.txt","r",stdin);
int i,j,a,b;
while(~scanf("%d",&Nx)){
memset(g,0,sizeof(g));
for(i=0;i<Nx;i++){
scanf("%d",&Ny);
for(j=0;j<Ny;j++){
scanf("%d %d",&a,&b);
g[i][(a-1)*12+b-1]=1;
}
}
printf("%d\n",MaxMatch());
}
return 0;
}