题意:
有n个科目,m个学生,每个科目都有一些学生去学,但是现在每个科目只能有一个学生选择,是否每个科目都能有学生选上。
题解:
这题抽象就是求|最大边独立集|,|最大边独立集|=最大匹配数
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> #define B(x) (1<<(x)) using namespace std; typedef long long ll; void cmax(int& a,int b){ if(b>a)a=b; } void cmin(int& a,int b){ if(b<a)a=b; } void cmax(ll& a,ll b){ if(b>a)a=b; } void cmin(ll& a,ll b){ if(b<a)a=b; } void add(int& a,int b,int mod){ a=(a+b)%mod; } void add(ll& a,ll b,ll mod){ a=(a+b)%mod; } const int oo=0x3f3f3f3f; const int MOD=1000000007; const int maxn=405; int n,m; int g[maxn][maxn],vis[maxn],mat[maxn]; int dfs(int u){ for(int i=1;i<=m;i++){ if(g[u][i]&&!vis[i]){ vis[i]=1; if(mat[i]==-1||dfs(mat[i])){ mat[i]=u; return 1; } } } return 0; } int Match(){ memset(mat,-1,sizeof mat); int ans=0; for(int i=1;i<=n;i++){ memset(vis,0,sizeof vis); ans+=dfs(i); } return ans; } int main(){ //freopen("E:\\read.txt","r",stdin); int u,v,k,T; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); memset(g,0,sizeof g); for(int u=1;u<=n;u++){ scanf("%d",&k); while(k--){ scanf("%d",&v); g[u][v]=1; } } if(Match()==n) printf("YES\n"); else printf("NO\n"); } return 0; }