Description
Sample Input
2 3 3 3 1 2 3 2 1 2 1 1 3 3 2 1 3 2 1 3 1 1
Sample Output
YES NO
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
int map[502][502];
bool visited[502]; //标记男生是否被访问
int match[502]; //女生和男生的匹配情况
int n,m;
bool find(int i) //查找当前的i是否可以匹配
{
int j;
for(j=1;j<=n;j++)
{
if(map[i][j]&&!visited[j])//在这里很有必要说一下visited这个数组,因为在之后的递归中,就会把这个标记好了的对象默认为
//已经和上一次的对象匹配过了,这样就不会再访问这个对象了,这在好几个的连续递归中显得尤为重要
{
visited[j]=1;
if(match[j]==-1||find(match[j])) //在此次查找的时候其实如果已经匹配过了则会在调用的时候即使是已经匹配成功了,由于
//当时在匹配的时候已经对可以匹配成功的做了match的标记了,就会继续查找他的下一个
//能够匹配的对象
{
match[j]=i;
return 1;
}
}
}
return 0;
}
int main()
{
int k,x,y,ans,tmp;
int T;
scanf("%d",&T);
while(T--)
{
ans=0;
memset(map,0,sizeof(map));
memset(match,-1,sizeof(match));
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)//对有意思的进行初始化
{
scanf("%d",&tmp);
for(int j=0;j<tmp;j++){
scanf("%d",&y);
map[i][y]=1;
}
}
for(int i=1;i<=m;i++)
{
memset(visited,0,sizeof(visited));//开始标记为全部没有访问
if(find(i)) //查找当前的i是否可以匹配成功
ans++;
}
printf("%s\n",ans>=m ? "YES" : "NO");
}
return 0;
}
原文:http://blog.csdn.net/u014665013/article/details/51344076