二分图(二部图):二部图就是可以将它的点划分为两个集合,然后所有的联通线都是连接这两个集合的。
匹配:为集合A的某个元素在集合B中找一个元素与它匹配。【过程就类似于相亲之类的】
最大匹配:尽可能的将AB中的元素组合成最多的对数。
算法:
匈牙利算法:基本思路是DFS,在为某个元素分配对象时,如果该对象被占用,试图让占用者去找新对象,若无,则匹配失败。
核心代码:
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
vector<int>Map[105];
int linker[305],p,n,total,m,r,t;
bool visit[305];
bool dfs(int s){
int len=Map[s].size(),p;
for(int i=0;i<len;i++){
if(!visit[Map[s][i]]){
p=Map[s][i];
visit[p]=true;
if(linker[p]==-1||dfs(linker[p])){
linker[p]=s;
return true;
}
}
}
return false;
}
void match(){
memset(linker,-1,sizeof(linker));
for(int i=1;i<=p;i++){
memset(visit,0,sizeof(visit));
if(dfs(i))total++;
}
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&p,&n);
for(int i=1;i<=p;i++){
scanf("%d",&m);
for(int j=1;j<=m;j++){
scanf("%d",&r);
Map[i].push_back(r);
}
}
if(n<p){printf("No");return 0;}
match();
printf("%s",total==p?"Yes":"No");
}
return 0;
}