关于本题二分图的匹配
关系始终是加单向边
用左边去匹配右边,match表示的是右边的人匹配的对应的左边的点
/* 关于本题二分图的匹配 链接的关系始终是单向边 用左边去匹配右边,match表示的是右边的人匹配的对应的左边的点 */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define maxn 505 int mp[maxn][maxn],match[maxn]; bool vis[maxn]; int p,n; bool dfs(int x){//第x门课是否有人匹配 for(int i=1;i<=n;i++){ if(!vis[i] && mp[x][i]){//枚举每门课可以选择的人 vis[i]=1; //第i个人已经匹配了match[i]课 if(match[i]==-1||dfs(match[i])){ match[i]=x;return 1; } } } return 0; } int sum(){ int res=0; for(int i=1;i<=p;i++){//每门课是否有学生来匹配 memset(vis,0,sizeof vis); if(dfs(i))res++; } return res; } void init(){ memset(match,-1,sizeof match); memset(mp,0,sizeof mp); } int main(){ int t;cin>>t; while(t--){ init(); cin>>p>>n;//p门课,n个学生 for(int i=1;i<=p;i++){//喜欢第i门课的学生有k个 int k,j;scanf("%d",&k); while(k--){ scanf("%d",&j); mp[i][j]=1; } } int ans=sum(); if(ans==p)puts("YES"); else puts("NO"); } }
原文地址:https://www.cnblogs.com/zsben991126/p/10886944.html
时间: 2024-10-18 22:26:21