ZOJ1140:Courses

来源:互联网 发布:淘宝有试衣功能吗 编辑:程序博客网 时间:2024/05/21 08:31

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1140

这题求解的是二分图的最大匹配,只要匹配住可以"盖住"每门课程,即匹配数与课程数量相等,委员会就可以成立。在这里集合课程中的元素是相互独立的,学生集合中的元素也是相互独立的,因而判定这个是二分图。然后采用二分图的匈牙利算法即可。

代码如下:

#include <iostream>#include <stdio.h>#include <string.h>using namespace std;#define MAXN 301int p ;int n ;bool course[MAXN][MAXN] ;//标记课程与学生之间的关系bool used[MAXN] ;//标记是否访问int match[MAXN] ;//记录之间的匹配情况bool dfs(int ) ;int maxmatch() ;int main(){int i ;int j ;int num ;int t ;int test ;//freopen("in.txt" , "r" , stdin) ;scanf("%d" , &test) ;while(test--){scanf("%d%d" ,&p , &n) ;memset(course , 0 , sizeof(course)) ;for( i = 1 ; i <= p ; i ++){scanf("%d" , &num) ;for(j = 0 ; j < num ; j ++){scanf("%d" , &t) ;course[i][t] = 1 ;}}if(maxmatch()==p)printf("YES\n") ;elseprintf("NO\n") ;}    return 0;}//求解二分图的最大匹配int maxmatch(){int i ;int matchnum = 0;memset(match , -1 , sizeof(match));for(i = 1 ; i <= p ; i ++){memset(used , 0 , sizeof(used)) ;if(dfs(i))matchnum ++ ;//累加匹配数if(matchnum == p)break ;}return matchnum ;//返回最大匹配数}bool dfs(int k)//dfs增广{int i ;int temp ;for(i = 1 ; i <= n ; i ++){//考虑学生集合中的所有元素,也即全部顶点if(course[k][i] && !used[i])//i与k邻接并且为访问过,{used[i] = 1 ;temp = match[i] ;match[i] = k ;//如果顶点i没匹配或者i已经匹配,但可以从match[i]出发可以找到一条增广路if(temp==-1 || dfs(temp))return 1 ;match[i] = temp ;}}return 0 ;}


原创粉丝点击