// poj4 1469 COURSES
// 题意: 现在有p门课程和n个学生,给出每门课程都有哪些学生可以参加.
// 问能否找到p个学生,满足每个学生代表一门课程而且每门课程只由一个学生代表
// 思路:求解二分图的最大匹配数,看与p是否相等
#include<iostream> //二分图的最大匹配
#include<cstring>
using namespace std;
int p,n;
int link[305]; // link[ b ] = a 表示 V2中的点b 与 V1中的点a 相匹配
int edge[105][305],vis[305];
// edge[a][b]=1表示V1中的a节点与V2中的b节点有边相连,vis记录V2中的点是否被访问过
int find(int a) //寻找有没有从V1中的点a开始的增广轨
{
for(int i=1;i<=n;++i)
{
if(edge[a][i]&&!vis[i]) //V2中节点i与a有边相连并且节点i未被访问过
{
vis[i]=1;
if( link[i]==0 || find(link[i]) )
{
link[i]=a;
return 1;
}
//如果V2中节点i未在前一个匹配M中
//或者V2中节点i已经在匹配M中,而与V2节点i匹配的在V1中的节点,从它出发找到了增广路
//则说明找到了从V1中的点a开始的增广轨
}
}
return 0;
}
int main()
{
int cases;
scanf("%d",&cases);
while(cases--)
{
memset(edge,0,sizeof(edge)); // 节点下标从1开始
memset(link,0,sizeof(link));
scanf("%d%d",&p,&n);
int m,t;
for(int i=1;i<=p;++i)
{
scanf("%d",&m);
while(m--)
{
scanf("%d",&t);
edge[i][t]=1;
}
}
int ans=0; // 二分图的最大匹配数
for(int i=1;i<=p;++i)
{
memset(vis,0,sizeof(vis)); //清空上次搜索时的标记
if(find(i)) //从V1中节点i尝试扩展
ans++;
}
if(ans==p)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
poj 1469 COURSES
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
poj1469 COURSES【二分图匹配】
#include <s
#include i++ ios -
POJ 1469 二分图最大匹配 COURSES
Description
i++ #include ide -
POJ1469_COURSES(二部图最大匹配)
解决报告http://blog.csdn.net/juncoder/article/details/38136
#include i++ #define ios 二分图 -
[POJ 2239] Selecting Courses
[题目链接] http://poj.org/problem?id=2239 [算法] 将课程作为左部节点,时间作为右部节点,用匈牙利算法求二分图最大匹配即可 [代码]
#include ios i++ 二分图 #define