这道题要我们找到p门课和n个学生是否存在一种关系,即在一个集合中的学生,
每人代表一门课,每门课在这个集合中也有一个代表。求的的最大匹配数是否等于课程总数。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define MAXN 305
bool map[105][MAXN], vis[MAXN];
int link[MAXN];
int p, n;
bool dfs(int u)
{
int v;
for( v = 1; v <= n; v++)
if( map[u][v] && !vis[v])
{
vis[v]=true;
if( link[v] == -1 || dfs(link[v]) )
{
link[v] = u;
return true;
}
}
return false;
}
int main()
{
int cas, u, k, v, ans;
scanf("%d", &cas);
while( cas--)
{
memset( map, false, sizeof(map));
scanf("%d%d", &p, &n);
for( u = 1; u <= p; u++)
{
scanf("%d", &k);
while( k--)
{
scanf("%d", &v);
map[u][v]=true;
}
}
ans = 0;
memset( link, -1, sizeof(link) );
for( u = 1; u <= p; u++)
{
memset( vis, false, sizeof(vis) );
if(dfs(u)) ans++;
}
if( ans == p)
printf("YES\n");
else printf("NO\n");
}
return 0;
}
看了CSGrandeur大牛的代码,我们得到了另一种方法,同样是匈牙利算法,我们只需将MaxMatch函数做一定改变,
给每一个课程u找匹配,当有一个u找不到与之匹配的学生v,就返回false,代码如下:
/*Accepted 200K 438MS C++ 1048B 2012-04-14 10:45:47 */ #include<cstdio> #include<cstring> #include<cstdlib> const int MAXP = 105, MAXN = 305; bool g[MAXP][MAXN], chk[MAXN]; int xM[MAXP], yM[MAXN]; int p, n; bool SearchPath( int u) { int v; for( v = 1; v <= n; v ++) if( g[u][v] && !chk[v]) { chk[v] = true; if( yM[v] == -1 || SearchPath( yM[v]) ) { yM[v] = u; xM[u] = v; return true; } } return false; } bool MaxMatch() { int u; memset( xM, -1, sizeof xM); memset( yM, -1, sizeof yM); for( u = 1; u <= p; u ++ ) if( xM[u] == -1) { memset( chk, false, sizeof chk); if( !SearchPath(u) ) return false; } return true; } void Read_Gragh() { scanf( "%d%d", &p, &n); int t; memset( g, false, sizeof g); for( int i = 1; i <= p; i ++) { scanf( "%d", &t); while( t --) { int j; scanf( "%d", &j); g[i][j] = true; } } } int main() { int T; scanf( "%d", &T); while( T --) { Read_Gragh(); if( MaxMatch() ) printf( "YES\n"); else printf( "NO\n"); } return 0; }