/* THE PROGRAM IS MADE BY PYY */
/*----------------------------------------------------------------------------//
Copyright (c) 2011 panyanyany All rights reserved.
URL : http://poj.org/problem?id=2239
Name : 2239 Selecting Courses
Date : Monday, November 28, 2011
Time Stage : one hour
Result:
9607451 panyanyany
2239
Accepted 256K 32MS C++
1360B 2011-11-28 20:46:55
Test Data :
Review :
前言:
貌似是比较裸的二分图之最大匹配,也许是因为最近做的题相对多一点吧,所以比较容易
看出来。
思路:
把所有的课程(course)归类为一个点集,所有的课时(class)归类为另一个点集,
课程编号为:1,2,3,...,300 ;
课时编号为:1,2,3,...,84 (因为一星期共有 7*12 节课);
每个课程有n个课时,即课程与课时之间有n条连线(或边)
怎样才能上最多的课,即求课程与课时之间的最大匹配
//----------------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std ;
#define MAXCOURSE 301
#define MAXCLASS 85
int n, t, p, q ;
int link[MAXCOURSE] ;
bool cover[MAXCLASS] ;
vector<int> graph[MAXCOURSE] ;
bool find (int cur)
{
int i, j ;
for (i = 0 ; i < graph[cur].size () ; ++i)
{
j = graph[cur][i] ;
if (cover[j] == false)
{
cover[j] = true ;
if (link[j] == 0 || find (link[j]))
{
link[j] = cur ;
return true ;
}
}
}
return false ;
}
int main ()
{
int i, j ;
int x, y ;
int sum ;
while (~scanf ("%d", &n))
{
for (i = 1 ; i <= n ; ++i)
{
graph[i].clear () ;
scanf ("%d", &t) ;
for (j = 1 ; j <= t ; ++j)
{
scanf ("%d%d", &x, &y) ;
graph[i].push_back ((x-1)*12 + y) ;
}
}
sum = 0 ;
memset (link, 0, sizeof (link)) ;
for (i = 1 ; i <= n ; ++i)
{
memset (cover, 0, sizeof (cover)) ;
sum += find (i) ;
}
printf ("%d\n", sum) ;
}
return 0 ;
}