您的位置:首页 > 职场人生

程序员技术练级攻略

2012-03-26 00:53 169 查看
 

/* 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 ;
}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: