趣味匈牙利算法(DFS方法详解)
但是首先要分清楚这二分匹配是如何匹配的
是拿谁去匹配谁
主要表现为存图问题
这道题的图是如何存的,到底是存双向图还是存单向图
根据题意的理解,好像是每个学生可以匹配课程,也可以课程匹配学生
乍一看好像是个双向图~~~
但是这里用双向图就会很悲惨的WA
但是仔细读题,学生要比课程多····
意思就是,可能课程匹配完了,还剩下很多的学生
而我们要的结果是课程必须匹配学生,但是学生可以有剩余
那么用学生去匹配课程
即:对于每一个课程,我们都用DFS去寻找相对应的学生
如果反了会造成什么样的后果?
match里面存的变为学生对应的课程
如果学生数小于课程数,那么也会有可能输出YES
#include<bits/stdc++.h>
using namespace std;
const int maxn=310;
bool e[maxn][maxn];
bool vis[maxn];
int match[maxn];
int p,n;
bool find(int u)
{
for(int i=1; i<=n; i++) //这里是N不是P(p代表课程,n代表人数)
{
if(!vis[i]&&e[u][i])
{
vis[i]=1;
if(!match[i]||find(match[i]))
{
match[i]=u;
return true;
}
}
}
return false;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(e,0,sizeof(e));
scanf("%d%d",&p,&n);
for(int i=1; i<=p; i++)//输入
{
int m,x;
scanf("%d",&m);
for(int j=1; j<=m; j++) //存图
{
scanf("%d",&x);
e[i][x]=1; //只能存单向图,存双向图会WA
}
}
int flag=0;
memset(match,0,sizeof(match));
for(int i=1; i<=p; i++)//对于每一门的课程,寻找与之匹配的学生
{
memset(vis,0,sizeof(vis));
if(find(i))
{
flag++;
}
}
if(flag!=p)
printf("NO\n");
else
printf("YES\n");
}
}