题意:
有N个学生和P门课程,让你判断能否构成最大匹配。先输入一个T,表示有T组测试数据;在输入N和P,P表示有P门课程,N表示有N个学生。之后有P行,比如:
a a1 a2 a3 a4 a5---第一行。1与a1,a2,a3,a4,a5有匹配。
b b1 b2 b3-----第二行。2与b1,b2,b3有匹配。
如果匹配数等于学生数目则YES;否则为NO;
上交模板,因为用了bfs增广一系列路径,所以更快……
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #define PI acos(-1.0) #define mem(a,b) memset(a,b,sizeof(a)) #define sca(a) scanf("%d",&a) #define sc(a,b) scanf("%d%d",&a,&b) #define pri(a) printf("%d\n",a) #define lson i<<1,l,mid #define rson i<<1|1,mid+1,r #define MM 50005 #define MN 500 #define INF 0x7fffffff #define eps 1e-7 using namespace std; typedef long long ll; int nx,ny,vis[MM],mx[MM],my[MM],dx[MM],dy[MM]; vector<int>e[MM]; queue<int>q; bool dfs(int u) { int i,l=e[u].size(); for(i=0;i<l;i++) { int v=e[u][i]; if(!vis[v]&&dy[v]==dx[u]+1) { vis[v]=1; if(!my[v]||dfs(my[v])) { mx[u]=v; my[v]=u; return true; } } } return false; } int HK() //Hopcroft_Karp算法 { mem(mx,0); mem(my,0); int ans=0; while(1) { int flag=0,i; while(!q.empty()) q.pop(); mem(dx,0); mem(dy,0); for(i=1;i<=nx;i++) if(!mx[i]) q.push(i); while(!q.empty()) { int u=q.front(),l=e[u].size(); q.pop(); for(i=0;i<l;i++) { int v=e[u][i]; if(!dy[v]) { dy[v]=dx[u]+1; if(my[v]) { dx[my[v]]=dy[v]+1; q.push(my[v]); } else flag=1; } } } if(!flag) break; mem(vis,0); for(i=1;i<=nx;i++) if(!mx[i]&&dfs(i)) ans++; } return ans; } int main() { int t; sca(t); while(t--) { int u,v,i,a; sc(nx,ny); for(i=0;i<=nx;i++) e[i].clear(); for(u=1;u<=nx;u++) { sca(a); for(i=0;i<a;i++) sca(v),e[u].push_back(v); } puts(HK()==nx?"YES":"NO"); } return 0; }