pku 1469 courses
This post is written in Chinese. Please consider using Google Translate
首先建立二分图,把P门课程作为X集合,N个人作为Y集合,对二分图进行完备匹配判定。方法是用匈牙利算法求出最大匹配,判断最大匹配数是否为P即可。
/*
* Problem: pku1469 courses
* Author: Guo Jiabao
* Time: 2009.3.25 21:45
* State: Solved
* Memo: 求完备匹配
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
const int MAXP=101,MAXN=301;
using namespace std;
struct edge
{
edge *next;
int t;
};
edge *V[MAXP];
edge ES[MAXN*MAXP];
int N,P,EC,Match[MAXN],mat;
bool vis[MAXN];
inline void addedge(int a,int b)
{
ES[++EC].next=V[a];
(V[a]=&ES[EC])->t=b;
}
void init()
{
int i,j,C,a;
scanf("%d%d",&P,&N);
EC=-1;
for (i=1;i<=P;i++)
{
scanf("%d",&C);
V[i]=0;
for (j=1;j<=C;j++)
{
scanf("%d",&a);
addedge(i,a);
}
}
memset(Match,0,sizeof(Match));
mat=0;
}
bool path(int i)
{
for (edge *k=V[i];k;k=k->next)
{
int j=k->t;
if (!vis[j])
{
vis[j]=true;
if (Match[j]==0 || path(Match[j]))
{
Match[j]=i;
return true;
}
}
}
return false;
}
void hungary()
{
for (int i=1;i<=P;i++)
{
memset(vis,0,sizeof(vis));
if (path(i))
mat++;
}
if (mat==P)
printf("YESn");
else
printf("NOn");
}
int main()
{
int i,T;
freopen("courses.in","r",stdin);
freopen("courses.out","w",stdout);
scanf("%d",&T);
for (i=1;i<=T;i++)
{
init();
hungary();
}
return 0;
}