题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1083
题目给出P门课程N个学生,然后给出对应选某门课程的学生编号。
每门课程必须要有一个不同的课代表。
一个学生也只能当一门课的课代表。
求图中是否存在这样的匹配。有的话输出YES,否则输出NO
二分图匹配入门题目,感觉题目描述有问题,英文是: every student in the committee represents a different course
every student 是每个学生代表一个不同的课,让我误以为P 和 N最后还要判别相等(害我Wa掉了)。
事实上是只要P门课能选出P个不同的课代表就行了,可能一部分学生不担任课代表。
比如第二组测试数据变成:
3 4
2 1 3
2 1 3
2 1 4
YES
AC代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int P,N; ///P门课,N个学生
const int maxn = 1000;
const int maxm = 100000;
int head[maxn];
int edgeNumber;
struct Edge
{
int u;
int v;
int nex;
}edge[maxm];
void addEdge(int u,int v)
{
edge[edgeNumber].u = u;
edge[edgeNumber].v = v;
edge[edgeNumber].nex = head[u];
head[u] = edgeNumber++;
}
int vis[maxn];
int match[maxn];
bool hungry(int x)
{
for(int i = head[x]; i != -1; i = edge[i].nex)
{
int y = edge[i].v;
if(vis[y]==0)
{
vis[y] = 1;
if(match[y]==0 || hungry(match[y]))
{
match[y] = x;
match[x] = y;
return true;
}
}
}
return false;
}
void solve()
{
int ans = 0;
memset(match,0,sizeof(match));
for(int i = 1; i <= P; i++)
{
memset(vis,0,sizeof(vis));
if(hungry(i+N))
ans++;
}
if(ans == P)
printf("YES\n");
else
printf("NO\n");
}
int main()
{
int ccount,x;
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&P,&N);
{
edgeNumber = 0;
memset(head,-1,sizeof(head));
for(int i = 1; i <= P; i++)
{
scanf("%d",&ccount);
while(ccount--)
{
scanf("%d",&x);
addEdge(x,i+N);
addEdge(i+N,x);
}
}
solve();
}
}
return 0;
}