View Code
题意大概是学校有多门课。没门课可能会在一个星期的每一天i(1<=i<=7)的第j(1<=j<=12)节课进行。求一个选课方案使得能选的课最多。
构造二分图,M={课程},N={课程举行的时间},然后构造M到N得二分图。这里将时间(i,j)映射为一个整数(i-1)*12+j用于构图。然后用匈牙利算法进行匹配就行了。
#include <iostream>
#include <cstring>
using namespace std;
int map[305][86],match[86],course[10][15 ];
bool vis[86];
int n,t;
bool findPath(int k)
{
for(int i = 1;i <= 84;++i)
{
if(!vis[i] && map[k][i])
{
vis[i] = true;
if(!match[i] || findPath(match[i]))
{
match[i] = k; return true;
}
}
}
return false;
}
int main()
{
int i,j,time1,time2;
for(i = 1;i <= 7;++i)
{
for(j = 1;j <= 12;++j) course[i][j] = (i-1)*12 + j;
}
while(scanf("%d",&n) != EOF)
{
memset(map,0,sizeof(map));
for(i = 1;i <= n;++i)
{
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&time1,&time2);
map[i][course[time1][time2]] = 1;
}
}
int ans = 0; memset(match,0,sizeof(match));
for(i = 1;i <= n;++i)
{
memset(vis,false,sizeof(vis));
if(findPath(i)) ans++;
}
printf("%d\n",ans);
}
return 0;
}