程序员技术练级攻略
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 ; }